BZOJ 2654 tree(二分答案+最小生成树)
2017-11-15 22:45
288 查看
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 10 1 1 1
0 1 2 0
Sample Output
2思路:
显而易见,这是一道最小生成树......
但是问题在于其中有黑白边及白边大小上的要求。当然我们能够发现,在忽略限制条件下求出的最小生成树里面的所有黑
边,也会在我们希望求的,有条件限制下的生成树中。接着我们知道,当最小生成树中白边数量超出我们的需求时,我们
会删去若干白边,并继续顺序加黑边。因此,我们要做到能够控制白边数量,根据kruskal的做法,我们发现选边的优先极
取决于边权,如果我们能够将白边的边权进行扩大,那么就可以做到控制白边数量了。接着,思考:当把所有白边都加上
一个偏移量offset之后,可以求出一棵最小生成树,再将答案减去树中所有白边的数量*offset,其实这就是一种合法的生
成树。
在选择不同的offset时,白边被偏移的大小使得我们能够控制白边进入树中的数量。offset过大导致选择的白边太少,反之
则太多。我们发现白边数量随offset的递增而递增,因此我们可以二分答案,二分offset的大小求解。
#include<iostream> #include<cstdlib> #include<cstdio> #include<algorithm> #include<vector> using namespace std; const int MAXE=100010; struct edge { int u,v,w,c; }E[MAXE]; int v,e,need,wn,ans,tot; int f[MAXE/2]; int find(int x) { return f[x]==x?x:f[x]=find(f[x]); } bool cmp(edge a,edge b) { return a.w==b.w?a.c<b.c:a.w<b.w; } int kruskal(int add) { for(int i=1;i<=v;i++) f[i]=i; for(int i=1;i<=e;i++) { if(!E[i].c) { E[i].w+=add; } } sort(E+1,E+1+e,cmp); int cnt=0,w=0;tot=0; for(int i=1;i<=e;i++) { if(find(E[i].u)!=find(E[i].v)) { f[find(E[i].u)]=find(E[i].v); cnt++;tot+=E[i].w; if(!E[i].c)w++; } if(cnt==v-1)break; } for(int i=1;i<=e;i++) { if(!E[i].c)E[i].w-=add; } return w; } int main() { cin>>v>>e>>need; for(int i=1;i<=e;i++) { cin>>E[i].u>>E[i].v>>E[i].w>>E[i].c; E[i].u++;E[i].v++; if(!E[i].c)wn++; } int l=-100,r=100; while(l<r) { int mid=(l+r)>>1; if(kruskal(mid)>=need){l=mid+1;ans=tot-wn*mid;} else r=mid-1; } cout<<ans<<endl; return 0; }
相关文章推荐
- bzoj 2654 tree (二分 + 最小生成树)
- 【bzoj2654】【二分+最小生成树】tree
- bzoj2654: tree(二分+最小生成树)
- [bzoj2654]tree(二分+最小生成树)
- 【二分+最小生成树】BZOJ2654[tree]题解
- [bzoj2654][最小生成树][二分]tree
- BZOJ2654 tree 【二分 + 最小生成树】
- BZOJ 2654 tree 详解(最小生成树 kruskal 二分)
- bzoj 2654: tree 二分+最小生成树
- bzoj 2654: tree (二分+最小生成树)
- BZOJ 2654: tree 最小生成树+二分
- 【二分+最小生成树】BZOJ2654 tree
- 【二分+最小生成树】bzoj2654 tree
- bzoj2654 二分答案+最小生成树
- 二分+最小生成树【bzoj2654】: tree
- BZOJ 2654 tree - 二分+最小生成树
- [bzoj2654]tree 二分+最小生成树
- 【BZOJ2654】tree 二分+最小生成树
- [bzoj2654]tree(最小生成树+二分)
- 【bzoj2654】【tree】【二分+最小生成树】