bzoj 2654: tree

 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 }

二分,给白色边加上的权值,看最小生成树中有多少白色的边。

你可能感兴趣的:(bzoj 2654: tree)