【NOIP2017练习&BZOJ4998】星球联盟(强联通分量,并查集)
题意:
在遥远的S星系中一共有N个星球,编号为1…N。其中的一些星球决定组成联盟,以方便相互间的交流。
但是,组成联盟的首要条件就是交通条件。初始时,在这N个星球间有M条太空隧道。每条太空隧道连接两个星球,使得它们能够相互到达。若两个星球属于同一个联盟,则必须存在一条环形线路经过这两个星球,即两个星球间存在两条没有公共隧道的路径。
为了壮大联盟的队伍,这些星球将建设P条新的太空隧道。这P条新隧道将按顺序依次建成。一条新轨道建成后,可能会使一些星球属于同一个联盟。你的任务是计算出,在一条新隧道建设完毕后,判断这条新轨道连接的两个星球是否属于同一个联盟,如果属于同一个联盟就计算出这个联盟中有多少个星球。
对于100%的数据有1≤N,M,P≤200000。
思路:
据说还可以用LCT+并查集维护连通性与size大小
1 var q,fa,size,f,a,b,c,h,head,vet,next,x,y:array[1..1100000]of longint; 2 n,m,p,i,j,u,e,v,t,tot,z,w:longint; 3 4 procedure add(a,b:longint); 5 begin 6 inc(tot); 7 next[tot]:=head[a]; 8 vet[tot]:=b; 9 head[a]:=tot; 10 end; 11 12 function find(k:longint):longint; 13 begin 14 if k=f[k] then exit(k); 15 f[k]:=find(f[k]); 16 exit(f[k]); 17 end; 18 19 function lca(x,y:longint):longint; 20 var t:longint; 21 begin 22 x:=find(x); y:=find(y); 23 if x=y then exit(x); 24 if h[x]>h[y] then 25 begin 26 t:=lca(fa[x],y); size[t]:=size[t]+size[x]; f[x]:=f[t]; 27 end; 28 if h[x]<=h[y] then 29 begin 30 t:=lca(fa[y],x); size[t]:=size[t]+size[y]; f[y]:=f[t]; 31 end; 32 exit(t); 33 end; 34 35 begin 36 assign(input,'bzoj4998.in'); reset(input); 37 assign(output,'bzoj4998.out'); rewrite(output); 38 readln(n,m,p); 39 for i:=1 to m do read(x[i],y[i]); 40 for i:=1 to p do 41 begin 42 read(x[m+i],y[m+i]); 43 b[m+i]:=1; 44 end; 45 m:=m+p; 46 for i:=1 to n do f[i]:=i; 47 for i:=1 to m do 48 begin 49 u:=x[i]; v:=y[i]; 50 if find(u)=find(v) then continue; 51 f[f[u]]:=f[v]; c[i]:=1; 52 add(u,v); add(v,u); 53 end; 54 for i:=1 to n do 55 begin 56 if h[i]>0 then continue; 57 t:=0; w:=1; q[1]:=i; h[i]:=1; 58 while t<w do 59 begin 60 inc(t); u:=q[t]; 61 e:=head[u]; 62 while e<>0 do 63 begin 64 v:=vet[e]; 65 if h[v]=0 then 66 begin 67 inc(w); q[w]:=v; h[v]:=h[u]+1; fa[v]:=u; 68 end; 69 e:=next[e]; 70 end; 71 end; 72 end; 73 for i:=1 to n do 74 begin 75 f[i]:=i; size[i]:=1; 76 end; 77 //for i:=1 to n do writeln(h[i]); 78 //for i:=1 to m do writeln(c[i]); 79 for i:=1 to m do 80 begin 81 if c[i]=1 then 82 begin 83 if b[i]=1 then writeln('No'); 84 continue; 85 end; 86 z:=lca(x[i],y[i]); 87 // writeln(z); 88 if b[i]=1 then writeln(size[z]); 89 end; 90 91 92 close(input); 93 close(output); 94 end.
null