标签:
题目链接:HDU - 1512
1 /*左偏树*/ 2 #include<iostream> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cmath> 7 #include<algorithm> 8 #define inf 0x7fffffff 9 using namespace std; 10 const int maxn = 100000+10; 11 12 int father[maxn]; 13 struct node 14 { 15 int l,r; 16 int dis; 17 int strong; 18 }LTree[maxn]; 19 int Find(int x) 20 { 21 if (father[x]==x) return x; 22 return father[x]=Find(father[x]); 23 } 24 int Merge(int x,int y) 25 { //返回合并后的根 26 if (x==0) return y; 27 if (y==0) return x; 28 if (LTree[x].strong < LTree[y].strong) //大顶堆 29 swap(x,y); 30 LTree[x].r = Merge(LTree[x].r,y); //递归合并右子树和Y 31 int l = LTree[x].l , r = LTree[x].r; 32 father[r] = x; //更新T右子树的根 33 if (LTree[l].dis < LTree[r].dis) //维护堆性质 34 swap(LTree[x].l,LTree[x].r); 35 if (LTree[x].r == 0) //如果没有右子树 则距离为0 36 LTree[x].dis = 0; 37 else 38 LTree[x].dis = LTree[LTree[x].r].dis + 1; 39 return x; 40 } 41 int del(int x) 42 { //返回删除根以后左右子树的合并的根 43 int l,r; 44 l=LTree[x].l; 45 r=LTree[x].r; 46 father[l]=l; 47 father[r]=r; 48 LTree[x].l=LTree[x].r=LTree[x].dis=0; 49 return Merge(l,r); 50 } 51 void solve(int x,int y) 52 { 53 LTree[x].strong /= 2; 54 LTree[y].strong /= 2; 55 //问每次PK以后,当前这个群体里力量最大的猴子的力量是多少。 56 int left,right; 57 left = del(x); 58 right = del(y); 59 left = Merge(left,x); 60 right = Merge(right,y); 61 left = Merge(left,right); 62 printf("%d\n",LTree[left].strong); 63 } 64 int main() 65 { 66 int n,m,x,y; 67 while (scanf("%d",&n)!=EOF) 68 { 69 for (int i=1 ;i<=n ;i++) 70 { 71 scanf("%d",<ree[i].strong); 72 LTree[i].l=0; 73 LTree[i].r=0; 74 LTree[i].dis=0; 75 father[i]=i; //起始已自己为父亲 76 } 77 scanf("%d",&m); 78 for (int i=1 ;i<=m ;i++) 79 { 80 scanf("%d%d",&x,&y); 81 int fx=Find(x),fy=Find(y); 82 if (fx == fy) printf("-1\n"); 83 else solve(fx,fy); 84 } 85 } 86 return 0; 87 }
标签:
原文地址:http://www.cnblogs.com/huangxf/p/4520408.html