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:
View Code
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 }