bzoj 2654 tree
来源:互联网 发布:matlab 定义二维数组 编辑:程序博客网 时间:2024/06/15 14:02
题目:
http://www.lydsy.com/JudgeOnline/problem.php?id=2654
2654: tree
Description
给你一个无向带权连通图,每条边是黑色或白色。让你求一棵最小权的恰好有need条白色边的生成树。
题目保证有解。
Input
第一行V,E,need分别表示点数,边数和需要的白色边数。
接下来E行,每行s,t,c,col表示这边的端点(点从0开始标号),边权,颜色(0白色1黑色)。
Output
一行表示所求生成树的边权和。
V<=50000,E<=100000,所有数据边权为[1,100]中的正整数。
Sample Input
2 2 1
0 1 1 1
0 1 2 0
Sample Output
2
题解:
奇怪的二分。。。
开始的想法是在mst过程中,跳过部分数量的黑边,二分这个数量,check图是否仍然联通,显然,有时跳过前面的黑边不如跳过后边的黑边优;
后来又想先建出有need条最短白边的连通图,再枚举删除哪一条黑边,被时限卡死,枚举是On,判断图是否联通On,且当前白边对图的连通性无贡献时,是否加入也是一个问题。成功hack两波~
正解是:二分一个值,使白边的权值加上这个值,做mst。
显然,不严格意义下:
此值增大,白边的数量减少;
此值减小,白边的数量减少。
细节
如果白边黑边权值相同,优先考虑白边(在cmp中体现);
因为看的题解,所以本来是没有考虑这个问题的;
会出现答案是mid,边数大于need
答案是mid+1边数小于need;
原因在于克鲁斯卡尔的加边顺序,此时一定有权值和对连通性贡献都相同的黑白边。
然而我的cpp可以去掉对于这个细节的处理:
可能是因为最后又做了一遍mst,具体原因等我去问问DQS学长;
在清澄上交,,wa,,被恶心了,等我明天做
代码:
#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int N=50000+500,M=100000+500;int num,ans,cnt,n,m,ned;struct edge{ int s,t,v,c,val;}e[M];int fa[N];bool cmp(edge a,edge b){ return a.val<b.val; if(a.val==b.val) return a.c<b.c;}int find(int x){ if(x==fa[x]) return x; return fa[x]=find(fa[x]);}void init(int x){ num=0; cnt=0; ans=0; for(int i=1;i<=m;i++) e[i].val=((e[i].c+1)%2)*x+e[i].v; sort(e+1,e+m+1,cmp); for(int i=0;i<=n;i++) fa[i]=i; }bool check(int x){ init(x); for(int i=1;i<=m;i++){ int x=find(e[i].s),y=find(e[i].t); if(x==y) continue; if(e[i].c==0) cnt++; num++; fa[x]=y; ans+=e[i].v; if(num==n-1) break; } if(cnt>=ned) return false; return true;}int main(){ scanf("%d%d%d",&n,&m,&ned); for(int i=1;i<=m;i++){ scanf("%d%d%d%d",&e[i].s,&e[i].t,&e[i].v,&e[i].c); } int l=-1000,r=1000; while(r-l>1){ int mid=r+l>>1; if(check(mid)) r=mid; else l=mid; } check(l); printf("%d",ans); return 0;}
- [bzoj 2654] tree
- BZOJ 2654 tree[Waiting]
- bzoj 2654 tree
- BZOJ 2654: tree
- bzoj 2654 tree
- BZOJ 2654 tree
- [Kruscal 二分] BZOJ 2654 tree
- BZOJ 2654: tree kruskal 二分
- BZOJ[2654]Tree 二分+Kruskal
- 【BZOJ】2654 tree 二分+kruskal
- BZOJ 2654 tree 二分+最小生成树
- [BZOJ 2654] tree · 二分答案
- BZOJ 2654 tree 二分答案+Kruskal
- bzoj 2654: tree 二分+最小生成树
- BZOJ 2654: tree (MST) 题解
- BZOJ 2654: tree 最小生成树+二分
- BZOJ 1468: Tree
- bzoj 1468: Tree
- windows下Eclipse调试ffmpeg
- Springboot 使用Redis注解
- python 列表转换成字符串输出
- 统计当前文件夹下的文件个数、目录个数
- 代码中创建网格
- bzoj 2654 tree
- C++—map的基本操作总结
- 编译原理(四) 消除回溯提取左因子法
- Activiti 分配组任务(三种方式)
- shiro权限管理
- 设计模式 外观模式
- SQL优化
- 快速排序算法小结
- Ubuntu 14.04 LTS 安装jdk1.8.0_91