2654:tree time limit:30 Sec Memory limit:512 MB
submit:610 solved:225
[Submit] [Status] [Discuss] Description
Give you a non-weighted connected graph with black or white on each side. Let you ask for a tree of the smallest power that happens to have need white edges.
The problem is guaranteed to be solved.
Input
The first line of V,e,need represents the number of points, the number of edges, and the white edges required.
Next E Line
Each line S,t,c,col represents the end point of this side (points starting from 0), Edge right, color (0 White 1 black).
Output
A row represents the Benquan and of the spanning tree being asked.
Sample Input2 2 1
0 1 1 1
0 1 2 0
Sample Output2
HINT
Data size and conventions
0:v<=10
1,2,3:v<=15
0,.., 19:v<=50000,e<=100000
All data edge weights are positive integers in [1,100].
Source
Just want to say well the ingenious idea ...
For each white edge, each time we give him a value of X (X∈[-101,101], because all edges are within this range), it is easy to see that as the X increases, the number of white edges in MST is gradually reduced, and we find the maximum number of white edges in MST when each white edge +x, So finding the first x,x-1 that is less than need is the x we need to find the MST at this point, the answer that is required.
#include <iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>#include<vector>#include<queue>using namespacestd;structnode{intU,v,w,c;} e[100005];intu[100005],v[100005],w[100005],c[100005],f[50005];intN,m,need,ans,sum,cnt,l,r;intFindintx) {returnx==f[x]?x:f[x]=find (F[x]);}BOOLCMP (node A,node b) {return((A.W<B.W) | | ((A.W==B.W) && (a.c<B.C))) ;}BOOLPdintx) {ans=0; cnt=0; for(intI=1; i<=n;i++) f[i]=i; for(intI=1; i<=m;i++) {e[i].u=u[i],e[i].v=v[i],e[i].w=w[i];e[i].c=C[i]; if(!c[i]) e[i].w+=x; } sort (E+1, e+m+1, CMP); for(intI=1; i<=m;i++) { intP=find (e[i].u), q=find (E[I].V); if(p!=q) {f[p]=P; Ans+=E[I].W; if(e[i].c==0) cnt++; } } returncnt>=need;} intMain () {scanf ("%d%d%d",&n,&m,&need); for(intI=1; i<=m;i++) {scanf ("%d%d%d%d",&u[i],&v[i],&w[i],&C[i]); U[i]++; v[i]++; } l=-101; R=101; while(l<=r) {intMid= (L+R)/2; if(PD (mid)) {L=mid+1; Sum=ans-need*mid; } Elser=mid-1; } printf ("%d", sum);}
[BZOJ2654] Tree