码迷,mamicode.com
首页 > 其他好文 > 详细

【NOI2002】银河英雄传说

时间:2017-11-01 14:56:31      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:include   包括   scanf   can   多少   return   std   main   style   

 1 #include<cstdio>
 2 #include<cstdlib>
 3 int T,x,y,p[30001],a[30001],r[30001]; //r[i]表示i号战舰和它的队头战舰之间的距离 
 4 char ch[2];                           //a[i]是代表为i的队一共有多少战舰
 5 void init(){                          //实际上,如果用r[x]表示数目的话对于只有一个结点和两个结点的情况 
 6     for(int i=1;i<=30000;i++)         //就不好区分,设为距离可以便于统一处理
 7         p[i]=i,a[i]=1;                //为什么需要a[],因为每次UNION操作是把队列置于另一个队列的队尾 
 8 }                                     //为了得到两个队头的距离,就需要有这样的记录 
 9 int find(int x){                      //始终注意到,UNION本质是对“代表元素”的操作 
10     if(x!=p[x]){
11         int px=find(p[x]);//找到当前结点x的根节点,同时在x以上的结点都完成了r[x]的更新,包括r[p[x]] 
12         r[x]+=r[p[x]];    //加上距离得到当前结点x对根节点px的距离 
13         p[x]=px;
14     }
15     return p[x];
16 }
17 void Union(int x,int y,int px,int py){
18     p[px]=py;             //直接设px指向py 
19     r[px]=a[py];          //那么此时px和py之间的距离就是py队列的元素数目 
20     a[py]+=a[px];         //因为实际上是把px置于py队尾,那么py队列现在的数目就是两者之和 
21 }
22 int main()
23 {
24     init();
25     scanf("%d",&T);
26     while(T--){
27         scanf("%s%d%d",ch,&x,&y);
28         int px=find(x),py=find(y); 
29         if(ch[0]==M) Union(x,y,px,py);
30         else{
31             if(px!=py) printf("-1\n");
32             else printf("%d\n",abs(r[x]-r[y])-1); //数目=距离-1 
33         }
34     }
35 }

 

【NOI2002】银河英雄传说

标签:include   包括   scanf   can   多少   return   std   main   style   

原文地址:http://www.cnblogs.com/sulley/p/7765894.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!