首页 > 代码库 > NOI2002银河英雄传说

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=Cthen
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.
View Code

1A……