1015: [JSOI2008]星球大战starwar - BZOJ
Description
很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互相直接或间接地连接。
但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每一次打击之后反抗军占据的星球的连通快的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。
Input
输入文件第一行包含两个整数,N
(1 <= N <= 2M) 和M (1 <= M <=
200,000),分别表示星球的数目和以太隧道的数目。星球用0~N-1的整数编号。接下来的M行,每行包括两个整数X,
Y,其中(0<=X<>Y
Output
输出文件的第一行是开始时星球的连通块个数。接下来的N行,每行一个整数,表示经过该次打击后现存星球的连通块个数。
Sample
Input
8 13
0 1
1 6
6 5
5 0
0 6
1 2
2 3
3 4
4
5
7 1
7 2
7 6
3 6
5
1
6
3
5
7
Sample
Output
1
1
1
2
3
3
用并查集维护联通块的信息,逆序处理摧毁的操作,因为并查集是用来合并的
先把一直没有被摧毁星球之间的边连起来,作为最后一个操作的回答
然后逆序加点,计算联通块个数
1 const 2 maxn=400010; 3 maxm=200010; 4 var 5 f,ans,s:array[0..maxn]of longint; 6 flag:array[0..maxn]of boolean; 7 first,last,next:array[0..maxn*2]of longint; 8 n,m,q,num,tot:longint; 9 10 procedure insert(x,y:longint); 11 begin 12 inc(tot); 13 last[tot]:=y; 14 next[tot]:=first[x]; 15 first[x]:=tot; 16 end; 17 18 function find(x:longint):longint; 19 begin 20 if f[x]=x then exit(x); 21 f[x]:=find(f[x]); 22 exit(f[x]); 23 end; 24 25 procedure init; 26 var 27 i,j,x,y:longint; 28 begin 29 read(n,m); 30 for i:=1 to n do 31 f[i]:=i; 32 for i:=1 to m do 33 begin 34 read(x,y); 35 insert(x+1,y+1); 36 insert(y+1,x+1); 37 end; 38 read(q); 39 for i:=1 to q do 40 begin 41 read(s[i]); 42 inc(s[i]); 43 if flag[s[i]]=false then flag[s[i]]:=true 44 else s[i]:=n+1; 45 end; 46 ans[q]:=n; 47 for i:=1 to n do 48 if flag[i]=false then 49 begin 50 j:=first[i]; 51 while j<>0 do 52 begin 53 if flag[last[j]]=false then 54 begin 55 if find(i)<>find(last[j]) then 56 begin 57 dec(ans[q]); 58 f[f[i]]:=f[last[j]]; 59 end; 60 end; 61 j:=next[j]; 62 end; 63 end 64 else dec(ans[q]); 65 end; 66 67 procedure work; 68 var 69 i,j:longint; 70 begin 71 for i:=q downto 1 do 72 if (flag[s[i]])and(s[i]<=n) then 73 begin 74 ans[i-1]:=ans[i]+1; 75 j:=first[s[i]]; 76 while j<>0 do 77 begin 78 if flag[last[j]]=false then 79 if find(s[i])<>find(last[j]) then 80 begin 81 dec(ans[i-1]); 82 f[f[s[i]]]:=f[last[j]]; 83 end; 84 j:=next[j]; 85 end; 86 flag[s[i]]:=false; 87 end 88 else ans[i-1]:=ans[i]; 89 for i:=0 to q do 90 writeln(ans[i]); 91 end; 92 93 begin 94 init; 95 work; 96 end.
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。