二分+最小生成树【bzoj2654】: tree
2018-10-26 18:10
344 查看
2654: tree
给你一个无向带权连通图,每条边是黑色或白色。让你求一棵最小权的恰好有need条白色边的生成树。
题目保证有解。
二分答案,然后跑最小生成树判断。
注意优先跑白色边。
code:
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int wx=500017; inline int read(){ int sum=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0'; ch=getchar();} return sum*f; } int fa[wx]; int n,m,k,tot,ans; struct node{ int x,y,d,flag; friend bool operator < (const node & a,const node & b){ return a.d<b.d; } }t[wx*2]; int find(int x){ if(x==fa[x])return x; return fa[x]=find(fa[x]); } bool ok(int now){ for(int i=1;i<=n;i++)fa[i]=i; int sum=0,tmp=0; for(int i=1;i<=m;i++){ if(t[i].flag)continue; int fx=find(t[i].x); int fy=find(t[i].y); if(fx==fy)continue; if(t[i].flag==0&&tmp>=k)continue; sum+=t[i].d; fa[fx]=fy; if(t[i].flag==0)tmp++; } for(int i=1;i<=m;i++){ int fx=find(t[i].x); int fy=find(t[i].y); if(fx==fy)continue; if(t[i].flag==0&&tmp>=k)continue; sum+=t[i].d; fa[fx]=fy; if(t[i].flag==0)tmp++; } return sum<=now&&tmp>=k; } int main(){ n=read(); m=read(); k=read(); for(int i=1;i<=m;i++){ int x,y,z,c; x=read(); y=read(); z=read(); c=read(); x++; y++; t[i].x=x; t[i].y=y; t[i].d=z; t[i].flag=c; tot+=z; } sort(t+1,t+1+m); int l=0,r=tot; while(l<=r){ int mid=l+r>>1; if(ok(mid))ans=mid,r=mid-1; else l=mid+1; } printf("%d\n",ans); return 0; }
相关文章推荐
- bzoj 2654: tree 二分+最小生成树
- [bzoj2654]tree(二分+最小生成树)
- 【二分+最小生成树】BZOJ2654[tree]题解
- BZOJ 2654: tree 最小生成树+二分
- BZOJ 2654 tree 详解(最小生成树 kruskal 二分)
- 【bzoj2654】【tree】【二分+最小生成树】
- [bzoj2654][最小生成树][二分]tree
- bzoj2654: tree(二分+最小生成树)
- BZOJ 2654 tree - 二分+最小生成树
- 【二分+最小生成树】BZOJ2654 tree
- bzoj 2654: tree (二分+最小生成树)
- 【二分+最小生成树】bzoj2654 tree
- [bzoj2654]tree(最小生成树+二分)
- BZOJ 2654 tree 二分+最小生成树
- bzoj 2654 tree (二分 + 最小生成树)
- BZOJ 2654 tree(二分答案+最小生成树)
- 【BZOJ2654】tree【二分】【最小生成树】
- [bzoj2654]tree 二分+最小生成树
- 【BZOJ2654】tree 二分+最小生成树
- 【bzoj2654】【二分+最小生成树】tree