【洛谷P1196】[NOI2002]银河英雄传说

银河英雄传说

题目链接

并查集时记录下以i为首的队列的长度(如果存在这个队列)num[i],便于合并

和点i到队首的距离front[i],便于查询(在find时维护)

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 #define N 30010
 6 #define abs(x) ((x)>0?(x):-(x))
 7 const int n=30000;
 8 int m,fa[N],front[N],num[N];
 9 inline int read(){
10     int x=0; char c=getchar();
11     while(c<'0'||c>'9') c=getchar();
12     while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }
13     return x;
14 }
15 inline int find(int x){
16     if(fa[x]==x) return x;
17     int fx=find(fa[x]);
18     front[x]+=front[fa[x]];  //改变fa[x]为祖先的同时要把fa[x]到祖先的长度加上
19     return fa[x]=fx;
20 }
21 int main()
22 {
23     for(int i=1;i<=n;i++){
24         fa[i]=i;
25         front[i]=0;
26         num[i]=1;
27     }
28     scanf("%d",&m);
29     char type[2];
30     int x,y;
31     while(m--){
32         scanf("%s",type);
33         x=read(); y=read();
34         int fx=find(x),fy=find(y);
35         if(type[0]=='M'){
36             fa[fx]=fy;
37             front[fx]+=num[fy];  //fx前面多了num[fy]个元素
38             num[fy]+=num[fx];   //fy的队列增长了num[fx]
39             num[fx]=0;      //fx的队列不存在了
40         }
41         else{
42             if(fx!=fy) puts("-1");
43             else
44              printf("%d\n",abs(front[x]-front[y])-1);
45         }
46     }
47     return 0;
48 }

 

posted @ 2018-07-26 15:26  yjk  阅读(146)  评论(0编辑  收藏  举报