Zoj 2334 Monkey King/left-side tree + query set, zoj2334
Original question link: http://acm.zju.edu.cn/onlinejudge/showProblem.do? ProblemId = 1389
N monkeys that do not know each other (each monkey has a combat power value)
There is a conflict between two unknown monkeys. The two monkeys will ask for the strongest one they know.
The monkey fights. After the duel, the two groups of monkeys knew each other.
The two monkeys in the duel are halved... M group inquiry
Input a B indicates that monkey a conflicts with B. If a and B belong to the same set, output-1
Otherwise, output the strongest combat power among the monkeys (merged) after the duel...
Train of Thought: Use and check the set to determine whether it belongs to the same set, and use the left tree to maintain the combat power of a group of monkeys.
Garbage collection is added, otherwise the memory will easily burst...
The details are as follows:
1 # include <cstdio> 2 # include <cstdlib> 3 # include <iostream> 4 # include <algorithm> 5 const int Max_N = 100050; 6 struct UnionFind {7 int par [Max_N], rank [Max_N]; 8 inline void init (int n) {9 for (int I = 1; I <= n; I ++) {10 par [I] = I; 11 rank [I] = 0; 12} 13} 14 inline int find (int x) {15 while (x! = Par [x]) {16 x = par [x] = par [par [x]; 17} 18 return x; 19} 20 inline void unite (int x, int y) {21 x = find (x), y = find (y); 22 if (x = y) return; 23 if (rank [x] <rank [y]) {24 par [x] = y; 25} else {26 par [y] = x; 27 if (rank [x] = rank [y]) rank [x] ++; 28} 29} 30}; 31 struct Node {32 int v, npl; 33 Node * ch [2]; 34 inline void set (int _ v = 0, int _ npl =-1, Node * p = NULL) {35 v = _ v, npl = _ Npl; 36 ch [0] = ch [1] = p; 37} 38 inline void push_up () {39 npl = ch [1]-> npl + 1; 40} 41}; 42 struct LeftistTree {43 int N, top; 44 UnionFind rec; 45 Node * tail, * null; 46 Node stack [Max_N], * ptr [Max_N], * store [Max_N]; 47 void init (int n) {48 tail = & stack [0]; 49 null = tail ++; 50 null-> set (); 51 N = n, top = 0, rec. init (n); 52} 53 inline Node * newNode (int v) {54 Node * p = null; 55 if (! Top) p = tail ++; 56 else p = store [-- top]; 57 p-> set (v, 0, null); 58 return p; 59} 60 inline Node * Merge (Node * & x, Node * & y) {61 if (x = null) return y; 62 if (y = null) return x; 63 if (y-> v> x-> v) std: swap (x, y ); 64 x-> ch [1] = Merge (x-> ch [1], y ); 65 if (x-> ch [1]-> npl> x-> ch [0]-> npl) 66 std: swap (x-> ch [0], x-> ch [1]); 67 x-> push_up (); 68 return x; 69} 70 inline int get_max (int I) {71 return Ptr [I]-> v; 72} 73 inline void insert () {74 int v; 75 for (int I = 1; I <= N; I ++) {76 scanf ("% d", & v); 77 ptr [I] = newNode (v); 78} 79} 80 inline void del (int I) {81 int ret = get_max (I); 82 Node * x = newNode (ret> 1); 83 store [top ++] = ptr [I]; 84 ptr [I] = Merge (ptr [I]-> ch [0], ptr [I]-> ch [1]); 85 ptr [I] = Merge (ptr [I], x); 86} 87 inline void gogo (int a, int B) {88 int ans = 0; 89 a = rec. find (), B = rec. find (B); 90 if (a = B) {91 printf ("-1 \ n"); 92 return; 93} 94 rec. unite (a, B); 95 del (a), del (B); 96 if (rec. rank [a]> rec. rank [B]) {97 ptr [a] = Merge (ptr [a], ptr [B]); 98 ans = ptr [a]-> v; 99} else {100 ptr [B] = Merge (ptr [a], ptr [B]); 101 ans = ptr [B]-> v; 102} 103 printf ("% d \ n", ans); 104} 105} lft; 106 int main () {107 # ifdef LOCAL108 freopen ("in.txt ", "r", stdin); 109 freopen ("out.txt", "w + ", Stdout); 110 # endif111 int n, m, a, B; 112 while (~ Scanf ("% d", & n) {113 lft. init (n), lft. insert (); 114 scanf ("% d", & m); 115 while (m --) {116 scanf ("% d", & a, & B ); 117 lft. gogo (a, B); 118} 119} 120 return 0; 121}View Code