乘积规划…神犇称其为隐式自适应凸包…
设每棵生成树为坐标系上的一个点,sigma(x[i])为横坐标,sigma(y[i])为纵坐标。则问题转化为求一个点,使得xy=k最小。
注意到这是一个反比例函数。所以显然的,有可能成为最优解的点集是一个凸包。
首先找到x最小的点A与y最小的点B,再找到离AB最远的点C,形成了一个三角形,这个三角形内部的点不可能成为最优答案(最优解的点集是一个凸包),所以我们继续递归AC,CB即可,对于找到的每一个点C尝试更新答案即可。
photo
怎么找到离一条直线最远的点呢?因为C离AB最远,所以S△ABC面积最大。即向量AB与向量AC的叉积最小(因为叉积是有向面积,是负数,所以取最小)
最小化:(B.x-A.x)(C.y-A.y)-(B.y-A.y)(C.x-A.x)
=(B.x-A.x)C.y+(A.y-B.y)*C.x - A.y(B.x-A.x)+A.x(B.y-A.y)
后面部分是常数,也就是最小化前面的部分。
将每条边的边权e[i].w设为e[i].t*(a.y-b.y)+e[i].c*(b.x-a.x);跑一遍最小生成树即可。
当叉积为正时,就是找不到一个那样的C点,return即可
有一个小技巧,kruskal记录下当前已经合并了的联通块的个数,是个小常数剪枝。还是比较有用的。
复杂度我也不知道…>_<…因为凸包上的点不会很多,所以速度应该还不错…如果谁能证明求告知…

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
//by:MirrorGray
using namespace std;
const int N=211111;
int n,m,fa[N];
struct P{int x,y;P(int a=0,int b=0){x=a;y=b;}P operator -(const P&b){return P(x-b.x,y-b.y);}friend int X(const P&a,const P&b){return a.x*b.y-a.y*b.x;}bool operator <(const P&b)const{if(x*y!=b.x*b.y)return x*y<b.x*b.y;return x<b.x;}void op(){printf("%d %d\n",x,y);}
}ans;
struct edge{int a,b,t,c,w;void read(){scanf("%d%d%d%d",&a,&b,&t,&c);a++;b++;}bool operator <(const edge&b)const{return w<b.w;}
}e[N];int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);
}P kruskal(){P ret;int tmp=0;sort(e+1,e+1+m);for(int i=1;i<=n;i++)fa[i]=i;for(int i=1;i<=m&&tmp<n-1;i++){int fx=find(e[i].a),fy=find(e[i].b);if(fx==fy)continue;tmp++;fa[fx]=fy;ret.x+=e[i].t;ret.y+=e[i].c;}ans=min(ans,ret);return ret;
}void solve(P a,P b){for(int i=1;i<=m;i++)e[i].w=e[i].t*(a.y-b.y)+e[i].c*(b.x-a.x);P c=kruskal();if(X(b-a,c-a)>=0)return ;solve(a,c);solve(c,b);
}int main(){scanf("%d%d",&n,&m);ans=P(40000,40000);for(int i=1;i<=m;i++)e[i].read();for(int i=1;i<=m;i++)e[i].w=e[i].t;P t1=kruskal();for(int i=1;i<=m;i++)e[i].w=e[i].c;P t2=kruskal();solve(t1,t2);ans.op();return 0;
}

BZOJ2395: [Balkan 2011]Timeismoney相关推荐

  1. 【BZOJ 2395】 [Balkan 2011]Timeismoney

    2395: [Balkan 2011]Timeismoney Time Limit: 10 Sec Memory Limit: 128 MB Submit: 304 Solved: 169 [Subm ...

  2. 【BZOJ】2395: [Balkan 2011]Timeismoney

    题解 最小乘积生成树! 我们把,x的总和和y的总和作为x坐标和y左边,画在坐标系上 我们选择两个初始点,一个是最靠近y轴的A,也就是x总和最小,一个是最靠近x轴的B,也就是y总和最小 连接两条直线,在 ...

  3. 微软CRM 2011 新功能之三:可新增客户化活动类型实体

    微软CRM4.0标准功能提供任务.传真 .电话联络.电子邮件.手机短信.约会.服务活动和市场活动响应等8种活动类型,除此之外无法 新增客户化的活动类型,随着社会的发展已经无法满足现代商业业务的需求,比 ...

  4. [Buzz.Today]2011.05.25

    >> VMWare的Open Source Pass - CloudFoundry VMWare推出了开源Pass:CloudFoundary,但是现在只是支持少数几种语言与环境:Java ...

  5. BZOJ 2440: [中山市选2011]完全平方数 [容斥原理 莫比乌斯函数]

    2440: [中山市选2011]完全平方数 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 3028  Solved: 1460 [Submit][S ...

  6. 重新开始 2011/11/25

    在csdn上写过几篇文章,始终没有坚持下来,也是由于自己没有一个明确的目标的缘故:当自己感觉乱的时候,总是想改变点东西,重新开始,改变了博客类的东西就真的能重新开始吗?现在我想换个博客就换个博客,这是 ...

  7. [scrum]2011/9/22-----第二天

    scrum 总结: Team member Yesterday's Work Today's Work Issue R X Task196:Completed xml 文件的解析,并且通过了两个测试用 ...

  8. 参与2011年7月13日举行的Azure国际猜拳锦标赛,赢取5,000美元大奖

    你想要编写自己的"bot"角色并测试你的技能,在线同来自美国,加拿大,中国,德国,新西兰,瑞典和英国的Windows Azure开发者一教高下,并赢取5,000美元大奖吗?请先注册 ...

  9. 靠数学“拿了”两次诺贝尔奖,彭罗斯从“铺地砖”帮忙发现2011年化学奖的秘密...

    晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI 诺贝尔奖没有数学奖,但是如果数学足够好的话,可以拿两次诺贝尔奖: 帮别人拿一次,自己再拿一次. 刚刚获得诺贝尔奖的英国数学家罗杰·彭罗斯( ...

最新文章

  1. 微服务架构的优势与不足
  2. jsp mysql 判断连接数据库失败 try_急……jsp 连接mysql不知道哪里出异常
  3. 核心期刊 CA JST CSCD 含金量_期刊评介|《仪表技术与传感器》科技期刊的阿玛尼,只管投就对了!...
  4. Nginx安装手冊以及图片server部署
  5. Python之Time模块
  6. Python 爬虫十六式 - 第六式:JQuery的假兄弟-pyquery
  7. 复制Oracle表的结构
  8. .net的retrofit--WebApiClient底层篇
  9. [翻译]运用文件解析器在任意文件中使用虚拟应用路径(~)
  10. 公司申请了网易企业电子邮箱,用手机端办公方便吗?
  11. 协议圣经(二) RTP组播音视频技巧
  12. Ubuntu 12.04 下安装 Eclipse
  13. 【FPGA的基础快速入门22-------OV7725摄像头模块】
  14. 无盘服务器易乐游,网维大师、易乐游无盘万兆性能评测
  15. canvas学习之-七色板
  16. 地方棋牌游戏里的家乡情结
  17. html写樱花树,写樱花树的作文
  18. 2.5D地图GIS系统技术方案
  19. FS116B FS 0.55A电流输出单通道玩具直流马达驱动器
  20. python freshman day2

热门文章

  1. C--一元二次方程求解
  2. Python3自动化打包项目发布到pypi
  3. 立创原理图导入AD后报错,显示空白的问题
  4. Python数据采集
  5. 如何在程序员中“C位出道”?
  6. 计算机运算器4个部件,第4章 计算机中的运算器部件(2).ppt
  7. opencv 之 双边滤波bilateralFilter
  8. 数据门户设计:想要自己的门户首页标新立异?Smartbi帮你
  9. 《韭菜的自我修养》电子书
  10. Reveal查看任意App界面以及解决由于Reveal版本更新导致的动态库文件过期的问题