Bzoj 1015
Thinking: And check set only the role of the side, can not be dismantled, so take reverse approach. First, the edge is removed, and then used and check set for the joint, the different connecting blocks connected to the number of Unicom block minus one.
1#include <bits/stdc++.h>2 #defineSe Second3 #defineFi first4 #definell Long Long5 #defineLS l,m,rt<<16 #defineRS M+1,r,rt<<1|17 #definePii pair<int,int>8 #definePB Push_back9 #defineFio Ios::sync_with_stdio (false); Cin.tie (0)Ten using namespacestd; One Const DoublePi=acos (-1.0); A Const intn=1e6+5; - using namespacestd; - intFa[n]; the inttot; - structnode{ - intu,v; -}q[200010]; + intA[n]; - BOOLVis[n]; + intAns[n]; Avector<int>Un[n]; at voidInit (intx) { - for(intI=0; i<=x;i++){ -fa[i]=i; - } - } - intFINDFA (intx) { in returnfa[x]==x?x:fa[x]=Findfa (fa[x]); - } to voidUniteintXinty) { +x=FINDFA (x); -y=Findfa (y); the if(x!=y) { *fa[y]=x; $tot--;//the number of unicom blocks is reduced by one by different connecting blocksPanax Notoginseng } - } the + intMain () { A intn,m; thescanf"%d%d",&n,&m); + init (n); - for(intI=0; i<m;i++){ $scanf"%d%d",&q[i].u,&q[i].v); $ } - intK; -scanf"%d",&k); the for(intI=1; i<=k;i++){ -scanf"%d",&a[i]);Wuyivis[a[i]]=1; the } -tot=n-K; Wu for(intI=0; i<m;i++){ - if(vis[q[i].u]| | VIS[Q[I].V]) {//if one side is removed, it will be two points to each other in the non-line array (two-way storage edge), otherwise the direct edge About UN[Q[I].U].PB (Q[I].V); $ UN[Q[I].V].PB (q[i].u); - } - Else { - Unite (Q[I].U,Q[I].V); A } + } theans[k+1]=tot; - for(intI=k;i>0; i--){ $tot++;//set the point as not hit point, and add one to the Unicom block, because more than one non-hit unicom block the intm=A[i]; thevis[m]=0; the for(intj=0; J<un[m].size (); j + +){ the if(!Vis[un[m][j]]) - Unite (M,un[m][j]); in } theans[i]=tot; the } About for(intI=1; i<=k+1; i++) printf ("%d\n", Ans[i]); the return 0; the}
Bzoj 1015 [JSOI2008] Star Wars Starwar (reverse and check)