给你一个无向带权连通图,每条边是黑色或白色。让你求一棵最小权的恰好有need条白色边的生成树。
题目保证有解。
标签:div font main 替换 using clu class 改变 sample
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 struct Edge 7 { 8 int u,v,dis,c; 9 }a[101001],E[101001]; 10 int ans=2e9,n,m,set[101001],need; 11 bool cmp(Edge a,Edge b) 12 { 13 if (a.dis==b.dis) 14 return a.c<b.c; 15 return a.dis<b.dis; 16 } 17 int find(int x) 18 { 19 if (set[x]!=x) set[x]=find(set[x]); 20 return set[x]; 21 } 22 bool check(int c) 23 {int i,j,cnt,s; 24 memcpy(a,E,sizeof(a)); 25 for (i=1;i<=m;i++) 26 if (a[i].c==0) 27 { 28 a[i].dis+=c; 29 } 30 sort(a+1,a+m+1,cmp); 31 for (i=0;i<=n;i++) 32 set[i]=i; 33 cnt=0;s=0;j=0; 34 for (i=1;i<=m;i++) 35 { 36 int p=find(a[i].u); 37 int q=find(a[i].v); 38 if (p!=q) 39 { 40 set[p]=q; 41 if (a[i].c==0) cnt++; 42 s+=a[i].dis; 43 j++; 44 if (j==n-1) break; 45 } 46 } 47 if (cnt<need) return 0; 48 else 49 { 50 ans=min(ans,s-need*c); 51 return 1; 52 } 53 } 54 int main() 55 {int i; 56 cin>>n>>m>>need; 57 for (i=1;i<=m;i++) 58 { 59 scanf("%d%d%d%d",&E[i].u,&E[i].v,&E[i].dis,&E[i].c); 60 } 61 int l=-100,r=100; 62 while (l<=r) 63 { 64 int mid=(l+r)/2; 65 if (check(mid)) l=mid+1; 66 else r=mid-1; 67 } 68 cout<<ans; 69 }
标签:div font main 替换 using clu class 改变 sample
原文地址:http://www.cnblogs.com/Y-E-T-I/p/7455284.html