3624: [Apio2008] Free road time limit:2 Sec Memory limit:128 mbsec Special Judge
submit:111 solved:49
[Submit] [Status] Description
Input
Output
Sample Input5 7 2
1 3 0
4 5 1
3 2 0
5 3 1
4 3 0
1 2 1
4 2 1
Sample Output3 2 0
4 3 0
5 3 1
1 2 1
or look at the online standard ..... The practice of this problem is first 1 side priority, do the spanning tree, if the number of 0 sides is greater than k no solution, or if you can add the 0 side to complement the K bar, the remaining by 1 side top up. How does this prove? We consider the first time to find the 0-side least spanning tree, when we randomly join a 0-side, to ensure that there is no 0-side ring, then we can delete a 1-side, the first spanning tree as far as possible to join the nature of the 1 side can be, then the above approach can be understood.
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespacestd;#defineMAXN 1000010structedge{intx, y;}; Vector<edge>V0,v1;BOOLVIS0[MAXN],VIS1[MAXN];intUF[MAXN];intGET_FA (intNow ) { return(uf[now]==now)? now:uf[now]=Get_fa (Uf[now]);}BOOLComb (intXinty) {x=Get_fa (x); Y=Get_fa (y); if(x==y)return 0; UF[X]=y; return 1;}intMain () {Freopen ("Input.txt","R", stdin); intn,m,i,j,k,x,y,z; intCnt=0;; inttot=0; scanf ("%d%d%d",&n,&m,&k); Edge et; for(i=0; i<=n;i++) Uf[i]=i; for(i=0; i<m;i++) {scanf ("%d%d%d",&et.x,&et.y,&z); if(z) v1.push_back (ET); Elsev0.push_back (ET); } for(i=0; I<v1.size (); i++) {comb (V1[I].X,V1[I].Y); } for(i=0; I<v0.size (); i++) {Vis0[i]=comb (V0[I].X,V0[I].Y); CNT+=Vis0[i]; } if(cnt>k) {printf ("No sulotion\n"); return 0; } for(i=0; i<=n;i++) Uf[i]=i; for(i=0; I<v0.size (); i++) { if(Vis0[i]) comb (V0[I].X,V0[I].Y); } for(i=0; I<v0.size (); i++) { if(cnt==k) Break; if(Vis0[i])Continue; Vis0[i]=comb (V0[I].X,V0[I].Y); CNT+=Vis0[i]; } for(i=0; I<v1.size (); i++) {Vis1[i]=comb (V1[I].X,V1[I].Y); } for(i=0; I<v0.size (); i++) if(Vis0[i]) tot++; for(i=0; I<v1.size (); i++) if(Vis1[i]) tot++; if(Cnt!=k | | tot!=n-1) {printf ("No solution\n"); return 0; } for(i=0; I<v0.size (); i++) if(Vis0[i]) printf ("%d%d%d\n", V0[i].x,v0[i].y,0); for(i=0; I<v1.size (); i++) if(Vis1[i]) printf ("%d%d%d\n", V1[i].x,v1[i].y,1);}
Bzoj 3624: [Apio2008] Construction of free road spanning tree