bzoj 1015 并查集
逆向思维,先将整张图以最后所有要求的点毁掉的状态建图,然后倒着
加点就行了,用并查集维护连通块
/************************************************************** Problem: 1015 User: BLADEVIL Language: Pascal Result: Accepted Time:2588 ms Memory:16340 kb ****************************************************************/ //By BLADEVIL var n, m, k :longint; flag :array[0..500010] of boolean; pre, other, last :array[0..500010] of longint; delete, x, y, ans :array[0..500010] of longint; father :array[0..500010] of longint; l :longint; procedure connect(x,y:longint); begin inc(l); pre[l]:=last[x]; last[x]:=l; other[l]:=y; end; procedure init; var i :longint; begin read(n,m); for i:=1 to m do begin read(x[i],y[i]); connect(x[i],y[i]); connect(y[i],x[i]); end; read(k); for i:=1 to k do begin read(delete[i]); flag[delete[i]]:=true; end; end; function getfather(x:longint):longint; begin if father[x]=x then exit(x); father[x]:=getfather(father[x]); exit(father[x]); end; procedure main; var i :longint; fa, fb :longint; cur :longint; q, p :longint; begin for i:=0 to n-1 do father[i]:=i; for i:=1 to m do begin if (not flag[x[i]]) and (not flag[y[i]]) then begin fa:=getfather(x[i]); fb:=getfather(y[i]); if fa<>fb then father[fa]:=fb; end; end; for i:=0 to n do if (not flag[i]) and (father[i]=i) then inc(ans[k+1]); for i:=k downto 1 do begin cur:=delete[i]; ans[i]:=ans[i+1]; q:=last[cur]; inc(ans[i]); while q<>0 do begin p:=other[q]; if not flag[p] then begin fa:=getfather(p); if fa<>cur then begin dec(ans[i]); father[fa]:=cur; end; end; q:=pre[q]; end; flag[cur]:=false; end; for i:=1 to k+1 do writeln(ans[i]); end; begin init; main; end.