并查集/poj 1988 Cube Stacking

题意

  一开始若干个元素自己为一个栈,给出n个操作,有如下两种:

    1.M a b :表示把元素a所在的栈整个压在含有元素b的栈的顶端

    2.C x :查询元素x所在的栈,x下方有几个元素,输出

分析

  题意简单明了:并查集

  除了数组f[i]用来记录i的祖先,也就是顶端元素

  另需要数组rank[i],记录i所在的栈一共有多少个元素(i为栈顶)

       数组up[i],记录i上面有多少个元素

  则答案为rank[find(x)]-up[x]-1

 

  至于在find和union中如何维护rank和up:

    在find中只需维护up,即up[x]+=up[father[x]];

    在union中需要维护up和rank,这时候rank起作用了。

    例如将x所在的栈压在y所在栈顶端,则y所在栈的顶端father[y]上元素的个数即为x所在栈所有元素个数,即up[father[y]]=rank[father[x]]

    (看了好多题解 表示不明白他们为什么要写up[father[y]]+=rank[father[x]],个人觉得用不着+啊,而且+不+都能AC...躺倒)

    而将x所在的栈压在y所在栈顶端后,x所在栈的总元素个数将会加上y所在栈元素个数,即rank[father[x]]+=rank[father[y]]

 

Accepted Code

 1 {
 2      PROBLEM:poj 1988
 3      AUTHER:Rinyo
 4      MEMO:并查集
 5 }
 6 
 7 Program poj1988;
 8 Const
 9   Infile = 'poj1988.in';
10   Outfile = 'poj1988.out';
11 Var
12   f,rank,up:Array[0..30030]Of Longint;
13   n,i,a,b:Longint;
14   ch:Char;
15 Function find(x:Longint):Longint;
16 Var
17   fx:Longint;
18 Begin
19   If f[x]=x Then Exit(x);
20   fx:=f[x];
21   f[x]:=find(fx);
22   up[x]:=up[x]+up[fx];
23   Exit(f[x]);
24 End;
25 Procedure union(x,y:Longint);
26 Var
27   fx,fy:Longint;
28 Begin
29   fx:=find(f[x]);fy:=find(f[y]);
30   If fx<>fy Then Begin
31     f[fy]:=fx;
32     up[fy]:=rank[fx];
33     rank[fx]:=rank[fx]+rank[fy];
34   End;
35 End;
36 
37 Begin
38   Assign(input,infile);Reset(input);
39   Assign(output,outfile);Rewrite(output);
40   ReadLn(n);
41   For i:=0 To 30030 Do rank[i]:=1;
42   Fillchar(up,sizeof(up),0);
43   For i:=0 To 30030 Do f[i]:=i;
44   For i:=1 To n Do Begin
45     Read(ch);
46     If ch='M' Then Begin
47       ReadLn(a,b);
48       union(a,b);
49     End Else Begin
50       ReadLn(a);
51       WriteLn(rank[find(a)]-up[a]-1);
52     End;
53   End;
54   Close(input);Close(output);
55 End.

 

posted @ 2013-02-23 19:04  Rinyo  阅读(396)  评论(2编辑  收藏  举报