并查集/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.

 

你可能感兴趣的:(stack)