HDU1512 Monkey King

题目来源HDU1512-Monkey King

这道题目题目大意就是,刚开始有N个猴子,他们有一个战斗力

他们互相并不认识

使他们认识的唯一条件就是两个人干一发打一架

他们中会有M次打架发生,如果两个人互相认识了,他们就打不起来了,输出-1,

如果两个人不认识,那他们就会搞起来~两个人在搞完后战斗力会减半

随后两个人就会认识,并且这道题目里告诉我们朋友的朋友还是朋友~~~

输出这个块内战斗力最大是多少~~~

虽然我的解释比较简洁冗长,但是还是把题目大意说清楚了复杂了

这就是一道左偏树的裸题嘛

我们用并查集维护两个元素是否在同一个集合里

因为左偏树中已经存下了root,所以我们用起来就更爽了

虽然好简单啊啊啊啊啊

但是手贱的我犯下了一个极大的错误

  1 #include <cmath>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 #define ll long long
  7 #define fo(i,x,y) for(int i=x; i<=y; i++)
  8 #define pr(i,x,y) for(int i=x; i>=y; i--)
  9 #define clear(a,x) memset(a,x,sizeof(a))
 10 #define INF 1e9
 11 #define EPS 1e-8
 12 #define LiQin 1 > 0
 13 
 14 using namespace std;
 15 
 16 struct node
 17 {
 18     int l,r,d,w,root;    
 19 } tree[1000005];
 20 
 21 int N,M;
 22 
 23 inline ll read()
 24 { 
 25     int f=1;
 26     ll Tmp=0;
 27     char ch=getchar();
 28     while (ch != '-' && ch < '0' || ch > '9')
 29     {
 30         ch=getchar();
 31     }
 32     if (ch == '-')
 33     {
 34         f=-1;
 35         ch=getchar();
 36     }
 37     while (ch >= '0' && ch <= '9')
 38     {
 39         Tmp=Tmp * 10 + ch - 48;
 40         ch=getchar();
 41     }
 42     return Tmp * f;
 43 }
 44 
 45 int merge(int A,int B)
 46 {
 47     if (A == 0)
 48     {
 49         return B;
 50     }
 51     if (B == 0)
 52     {
 53         return A;
 54     }
 55     if (tree[A].w < tree[B].w)
 56     {
 57         swap(A,B);
 58     }
 59     tree[A].r=merge(tree[A].r,B);
 60     tree[tree[A].r].root=A;
 61     if (tree[tree[A].l].d < tree[tree[A].r].d)
 62     {
 63         swap(tree[tree[A].l].d , tree[tree[A].r].d);//相信大佬们已经看出来了,这里交换的是左右儿子,而不是左右儿子的dist
 64     }
 65     if (tree[A].r)
 66     {
 67         tree[A].d=tree[tree[A].r].d + 1;
 68     }
 69     else
 70     {
 71         tree[A].d=0;
 72     }
 73     return A;
 74 }
 75 
 76 int pop(int u)
 77 {
 78     int L=tree[u].l; int R=tree[u].r;
 79     tree[u].l=tree[u].r=tree[u].d=0;
 80     tree[L].root=L; tree[R].root=R;
 81     return merge(L,R);
 82 }
 83 
 84 int find1(int X)
 85 {
 86     if (tree[X].root != X) 
 87     {
 88         return find1(tree[X].root);
 89     }
 90     else return X;
 91 }
 92 
 93 void solve(int u,int v)
 94 {
 95     int fx=find1(u); int fy=find1(v);
 96     tree[fx].w/=2; tree[fy].w/=2;
 97     int XXX=pop(fx); int YYY=pop(fy);
 98     XXX=merge(XXX,fx);
 99     YYY=merge(YYY,fy);
100     XXX=merge(XXX,YYY);
101     printf("%d\n",tree[XXX].w);
102 }
103 
104 void Init()
105 {
106     fo(i,1,N)
107     {
108         tree[i].root=i;
109         tree[i].l=tree[i].r=tree[i].d=0;
110     }
111 }
112 
113 int main()
114 {
115     while (scanf("%d",&N) == 1)
116     {
117         Init();
118         fo(i,1,N)
119         {
120             tree[i].w=read();
121         }
122         M=read();
123         while (M--)
124         {
125             int u=read();
126             int v=read();
127             int fx=find1(u);
128             int fy=find1(v);
129             if (fx == fy)
130             {
131                 printf("-1\n");
132             }
133             else
134             {
135                 solve(u,v);
136             }
137         }
138     }
139 }
View Code

好了好了

下面才是AC代码

  1 #include <cmath>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 #define ll long long
  7 #define fo(i,x,y) for(int i=x; i<=y; i++)
  8 #define pr(i,x,y) for(int i=x; i>=y; i--)
  9 #define clear(a,x) memset(a,x,sizeof(a))
 10 #define INF 1e9
 11 #define EPS 1e-8
 12 #define LiQin 1 > 0
 13 
 14 using namespace std;
 15 
 16 struct node
 17 {
 18     int l,r,d,w,root;    
 19 } tree[1000005];
 20 
 21 int N,M;
 22 
 23 inline ll read()
 24 { 
 25     int f=1;
 26     ll Tmp=0;
 27     char ch=getchar();
 28     while (ch != '-' && ch < '0' || ch > '9')
 29     {
 30         ch=getchar();
 31     }
 32     if (ch == '-')
 33     {
 34         f=-1;
 35         ch=getchar();
 36     }
 37     while (ch >= '0' && ch <= '9')
 38     {
 39         Tmp=Tmp * 10 + ch - 48;
 40         ch=getchar();
 41     }
 42     return Tmp * f;
 43 }
 44 
 45 int merge(int A,int B)
 46 {
 47     if (A == 0)
 48     {
 49         return B;
 50     }
 51     if (B == 0)
 52     {
 53         return A;
 54     }
 55     if (tree[A].w < tree[B].w)
 56     {
 57         swap(A,B);
 58     }
 59     tree[A].r=merge(tree[A].r,B);
 60     tree[tree[A].r].root=A;
 61     if (tree[tree[A].l].d < tree[tree[A].r].d)
 62     {
 63         swap(tree[A].l , tree[A].r);
 64     }
 65     if (tree[A].r)
 66     {
 67         tree[A].d=tree[tree[A].r].d + 1;
 68     }
 69     else
 70     {
 71         tree[A].d=0;
 72     }
 73     return A;
 74 }
 75 
 76 int pop(int u)
 77 {
 78     int L=tree[u].l; int R=tree[u].r;
 79     tree[u].l=tree[u].r=tree[u].d=0;
 80     tree[L].root=L; tree[R].root=R;
 81     return merge(L,R);
 82 }
 83 
 84 int find1(int X)
 85 {
 86     if (tree[X].root != X) tree[X].root=find1(tree[X].root);
 87     return tree[X].root;
 88 }
 89 
 90 void solve(int u,int v)
 91 {
 92     int fx=find1(u); int fy=find1(v);
 93     tree[fx].w/=2; tree[fy].w/=2;
 94     int XXX=pop(fx); int YYY=pop(fy);
 95     XXX=merge(XXX,fx);
 96     YYY=merge(YYY,fy);
 97     XXX=merge(XXX,YYY);
 98     printf("%d\n",tree[XXX].w);
 99 }
100 
101 int main()
102 {
103     while (scanf("%d",&N) == 1)
104     {
105         fo(i,1,N)
106         {
107             tree[i].w=read();
108             tree[i].root=i;
109             tree[i].l=tree[i].r=tree[i].d=0;
110         }
111         M=read();
112         while (M--)
113         {
114             int u=read();
115             int v=read();
116             int fx=find1(u);
117             int fy=find1(v);
118             if (fx == fy)
119             {
120                 printf("-1\n");
121             }
122             else
123             {
124                 solve(u,v);
125             }
126         }
127     }
128 }
View Code

 

posted @ 2017-09-03 19:39  雒煜翾  阅读(224)  评论(0编辑  收藏  举报