1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define M 100008 5 using namespace std; 6 struct data 7 { 8 int u,v,w,c; 9 }e[M]; 10 int n,m,m1,u[M],w[M],v[M],c[M],tot,fa[M],ans1; 11 bool cmp(data a,data b) 12 { 13 if(a.w==b.w) 14 return a.c<b.c; 15 return a.w<b.w; 16 } 17 int zhao(int a1) 18 { 19 if(fa[a1]==a1) 20 return a1; 21 fa[a1]=zhao(fa[a1]); 22 return fa[a1]; 23 } 24 bool ke(int a1) 25 { 26 int sum=0; 27 tot=0; 28 for(int i=1;i<=n;i++) 29 fa[i]=i; 30 for(int i=1;i<=m;i++) 31 { 32 e[i].u=u[i]; 33 e[i].v=v[i]; 34 e[i].w=w[i]; 35 e[i].c=c[i]; 36 if(!c[i]) 37 e[i].w+=a1; 38 } 39 sort(e+1,e+m+1,cmp); 40 for(int i=1;i<=m;i++) 41 { 42 int b1=zhao(e[i].u),b2=zhao(e[i].v); 43 if(b1!=b2) 44 { 45 fa[b2]=b1; 46 tot+=e[i].w; 47 if(!e[i].c) 48 sum++; 49 } 50 } 51 return sum>=m1; 52 } 53 int main() 54 { 55 scanf("%d%d%d",&n,&m,&m1); 56 for(int i=1;i<=m;i++) 57 { 58 scanf("%d%d%d%d",&u[i],&v[i],&w[i],&c[i]); 59 u[i]++; 60 v[i]++; 61 } 62 int l=-102,r=102; 63 for(;l<=r;) 64 { 65 int mid=(l+r)>>1; 66 if(ke(mid)) 67 { 68 ans1=tot-mid*m1; 69 l=mid+1; 70 } 71 else 72 r=mid-1; 73 } 74 printf("%d",ans1); 75 }
二分,给白色边加上的权值,看最小生成树中有多少白色的边。