【最小乘积生成树 】bzoj2395
来源:互联网 发布:罗素 作品 知乎 编辑:程序博客网 时间:2024/04/28 12:01
bzoj2395
以前听基哥讲的时候就没怎么懂,以为好难写好难写 // 其实不难写,只是有点难调。
利用数形结合的思想,每棵生成树在坐标系上对应的是点(sigma(a),sigma(b)), 那么,最小乘积生成树必定在某个k最小的反比例函数xy= k中。
先求出sigma(a)最小的点,sigma(b)最小的点,利用快包思想,找离这两点所连成的直线最远(往靠近原点那边)的点(生成树)c,得到一个三角形,三角形
内部的点是不如c优的,可以排除,然后递归处理a -->c ,c-->b的情况。
复杂度......如同自适应辛普森一样,不好确定复杂度,但是速度是可以相信的。
由于脑抽写了kruscal(图方便,prim丑了点),结果慢的一塌糊涂= 。 =,加了点小优化才过,不过仍然垫底。
不想改prim了,虽然prim也很好写。 这一次因祸得福终于学会调快排了= 。 =!,庆祝一下。
# include <cstdlib># include <cstdio># include <cmath>using namespace std;const int maxV= 10000+5;struct point{ int a,b,x,y; long long c; void read() { scanf("%d%d%d%d",&x,&y,&a,&b); x++,y++; }}ans,edge[maxV];int ufs[300];int n,m;int find(int x) {return ufs[x]==x? x:x= find(ufs[x]);};int cmp(const void *i, const void *j){ point p=*(point *)i, q=*(point *)j; if (p.c>q.c) return 1; else return -1;}inline point kruscal(){ int i,fx,fy; point p; p.a=p.b=0; int k = 0; for (i = 1; i <= n; i++) ufs[i] = i; for (i = 1; i <= m; i++) { fx = find(edge[i].x), fy = find(edge[i].y); if (fx!= fy) p.a+= edge[i].a, p.b+= edge[i].b, ufs[fx]=fy, k++; if (k == n-1) break; } if (1LL*ans.a*ans.b>1LL*p.a*p.b) ans = p; return p;}inline long long cross(long long x1, long long y1, long long x2, long long y2){return x1*y2-x2*y1;}void work(point blim, point alim){ int kb = alim.b-blim.b, ka= alim.a-blim.a, i; point p; for (i = 1; i <= m; i++) edge[i].c= 1LL*edge[i].a*kb-1LL*edge[i].b*ka; qsort(edge+1, m, sizeof(edge[1]), cmp); p = kruscal(); if (cross(1LL*alim.a-blim.a, 1LL*alim.b-blim.b, 1LL*p.a-blim.a, 1LL*p.b-blim.b) <=0) return; work(p, alim); work(blim, p);} int main(){ int i; point alim, blim; freopen("timeismoney.in", "r", stdin); freopen("timeismoney.out", "w", stdout); scanf("%d%d", &n, &m); ans.a=ans.b=1073740819; for (i = 1; i <= m; i++) edge[i].read(); for (i = 1; i <= m; i++) edge[i].c=edge[i].a; qsort(edge+1, m, sizeof(edge[1]),cmp); alim = kruscal(); for (i = 1; i <= m; i++) edge[i].c=edge[i].b; qsort(edge+1, m, sizeof(edge[1]),cmp); blim = kruscal(); work(blim, alim); printf("%d %d",ans.a, ans.b); return 0;}
- 【最小乘积生成树 】bzoj2395
- BZOJ2395【最小乘积生成树】
- 【最小乘积生成树详解】【BZOJ2395】
- bzoj2395 Timeismoney【最小乘积生成树】
- 【BZOJ2395】【Balkan 2011】Timeismoney 最小乘积生成树
- bzoj2395: [Balkan 2011]Timeismoney 最小乘积生成树
- 二维最小乘积生成树
- bzoj 2395(最小乘积生成树)
- 【BZOJ】【P2395】【Balkan 2011】【Timeismoney】【题解】【最小乘积生成树】
- [最小乘积生成树 分治] BZOJ 2395 [Balkan 2011]Timeismoney
- 最小乘积
- 最小乘积
- 最小乘积
- 最小乘积
- 最小乘积
- 最小乘积
- 最小乘积
- 最小乘积
- 自定义进度条(多边形)
- C-Free 5.0最新注册码
- 【最小路径覆盖】HDU 4160
- 上海镇保和城保的区别
- 要回学校了
- 【最小乘积生成树 】bzoj2395
- IIS架设安装顺序
- Oracle日常维护时需要用到的各种unix操作系统命令
- 手机应用推广必备发布渠道【安卓渠道汇】
- 终于连熊也可以代表了!
- session超时,处理ajax请求
- 2012.2.18
- 链表排序
- static