POJ1988 Cube Stacking (disjoint-set)

Topic links: http://poj.org/problem?id=1988

The meaning of problems: there are n elements, each element in a beginning of each stack, there are two operations, the stack containing the element x of y at the top of the stack containing, combined into a stack.
The second operation is to ask the following elements containing x number of elements.
Ideas:
Disjoint-set, to each pile as a stack, seen below the top of the stack heap. Because when we know the total number of elements in the stack, and an element to the distance "stack" of
We will be able to know how many elements under this element. When the merge operation, always use roots to do after the merger in the stack below the root, so that it reaches the roots of the stack is "stack" effect of the elements of the stack, we simply each "stack" in the total number of elements to the stack of records. However, we also need to know certain elements from the "stack", so we need to record each element from its father, put it on the root of the distance through which add up to it is the "stack" of distance. So we come to the result.
 
This figure is a key part of the time of the merger 
Further, during the Find () operation, there is an under [x] + = under [t [x] .parent]; this statement is a recursive looking at the root node, calculated for each element from the stack bottom (root )the distance.
  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<vector>
  6 #include<stack>
  7 #include<map>
  8 #include<set>
  9 #include<list>
 10 #include<queue>
 11 #include<string>
 12 #include<algorithm>
 13 #include<iomanip>
 14 using namespace std;
18{
17node
struct1615 
       int parent;
 19     int date;
 20 };
 21 
 22 int * total;
 23 int * under;
 24 
 25 class DisJoinSet
 26 {
 27 protected:
 28     int n;
 29     
 30     node * tree;
 31 public:
 32     DisJoinSet(int n);
 33     ~DisJoinSet();
 34     void Init();
 35     int Find(int x);
 36     void Union(int x,int y);
 37 };
 38 
 39 DisJoinSet::DisJoinSet(int n)
 40 {
 41     this->n = n;
 42     tree = new node[n+2];
 43     total = new int[n+2];
 44     under = new int[n+2];
 45     Init();
 46 }
 47 DisJoinSet::~DisJoinSet()
 48 {
 49     delete[] under;
 50     delete[] total;
 51     delete[] tree;
 52 }
 53 
 54 void DisJoinSet::Init()
 55 {
 56     for(int i = 1;i  <= n ;i ++)
 57     {
 58         tree[i].date  = i;
 59         tree[i].parent = i;
 60         total[i] = 1;
 61         under[i] = 0;
 62     }
 63 is  }
 64  int DisJoinSet :: the Find ( int X)
 65  {
 66      // int Tree TEMP = [X] .parent; 
67      IF (! X = Tree [X] .parent)
 68      {
 69          int PAR = the Find (Tree [X] .parent);
 70          an under [X] + = an under [Tree [X] .parent]; // the number of father nodes the following was added to his head 
71 is          Tree [X] = .parent PAR;
 72          return Tree [X] .parent;
 73 is      }
 74      the else 
75      {
 76          return X;
77      }
 78  }
 79  
80  void DisJoinSet :: of Union ( int X, int Y)
 81  {
 82      int PA = the Find (X);
 83      int Pb = the Find (Y);
 84      IF (PA == Pb) return ;
 85      the else 
86      {
 87          Tree [pa] .parent = Pb; // root of x becomes y where x is the root that is stacked on top of a pile where y 
88          an under [pa] = Total [Pb]; // at the pa the original number of elements in the stack, i.e., where y Total 
89          Total [Pb] + = Total [PA]; //更新y的totoal
 90     }
 91 }
 92 
 93 int main()
 94 {
 95     int p;
 96     while(scanf("%d",&p) != EOF)
 97     {
 98         if(p == 0)break;
 99         DisJoinSet dis(p);
100         char s1[2];
101         for(int i = 0 ;i < p ;i++)
102         {
103             
104             int s2;
105             int s3;
106             scanf("%s",s1);
107             if(s1[0] == 'M')
108             {
109                 scanf("%d%d",&s2,&s3);
110                 int pa = dis.Find(s2);
111                 int pb = dis.Find(s3);
112                 if(pa != pb)
113                 {
114                     dis.Union(s2,s3);
115                 }
116             }
117             if(s1[0] == 'C')
118             {
119                 scanf("%d",&s2);
120                 dis.Find(s2);
121                 cout<<under[s2]<<endl;
122             }
123         }
124         dis.~DisJoinSet();
125     }
126     return 0;
127 }
View Code

 

Guess you like

Origin www.cnblogs.com/ygsworld/p/11141079.html