NOI2002银河英雄传说
原先就看过这道题,觉得很复杂。
不知道为什么今天一看觉得好水啊……
难道这就是并查集的启发式合并?
数组d【i】表示i到其父节点的距离,即中间隔了多少船舰。
数组sum【i】记录以i为根的集合总共有多少个元素,将新节点插入的时候距离设为sum【i】就好了。
代码:
1 var fa,d,sum:array[0..30001] of longint; 2 t,i,xx,yy,x,y:longint; 3 ch:string[1]; 4 function find(x:longint):longint; 5 var tmp:longint; 6 begin 7 tmp:=fa[x]; 8 if fa[x]<>x then fa[x]:=find(fa[x]); 9 d[x]:=d[x]+d[tmp]; 10 exit(fa[x]); 11 end; 12 procedure main; 13 begin 14 readln(t); 15 for i:=1 to 30001 do begin fa[i]:=i;d[i]:=0;sum[i]:=1;end; 16 for i:=1 to t do 17 begin 18 readln(ch,x,y); 19 xx:=find(x);yy:=find(y); 20 if ch='C'then 21 begin 22 if xx<>yy then writeln('-1') else writeln(abs(d[y]-d[x])-1); 23 end 24 else 25 begin 26 fa[xx]:=yy;d[xx]:=sum[yy];inc(sum[yy],sum[xx]);sum[xx]:=0; 27 end; 28 end; 29 end; 30 begin 31 main; 32 end.
1A……