luoguP1196(带权并查集)

题目链接:https://www.luogu.org/problemnew/show/P1196

思路:

带权并查集。对每个结点,构造表示该结点的头结点,该结点距头结点的距离,该列的大小3个数组。

在合并过程中,要维护每个结点的权值,将x所在列的头结点接到y所在列的尾部,并修改xx距新头结点的距离,然后修改列的大小。

在查询过程中,也要维护每个结点的权值,计算两个结点的差值即可得到结果。

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 int t;
 5 int f[30005],l[30005],s[30005];
 6 
 7 int get(int k){
 8     if(f[k]==k) return k;
 9     else{
10         int tmp=f[k];
11         f[k]=get(f[k]);
12         l[k]+=l[tmp];
13         s[k]=s[f[k]];
14         return f[k];
15     }
16 }
17 
18 int main(){
19     scanf("%d",&t);
20     for(int i=1;i<=30000;i++)
21         f[i]=i,l[i]=0,s[i]=1;
22     char m;
23     int x,y;
24     while(t--){
25         scanf(" %c",&m);
26         scanf("%d%d",&x,&y);
27         int xx,yy;
28         if(m=='M'){
29             xx=get(x);
30             yy=get(y);
31             f[xx]=yy;
32             l[xx]=s[yy];
33             s[xx]+=s[yy];
34             s[yy]=s[xx];
35         }
36         else{
37             xx=get(x);
38             yy=get(y);
39             if(xx!=yy)
40                 printf("-1\n");
41             else
42                 printf("%d\n",abs(l[x]-l[y])-1);
43         }
44     }
45     return 0;
46 }

猜你喜欢

转载自www.cnblogs.com/FrankChen831X/p/10350987.html
今日推荐