银河英雄传说 - 带权并查集

题目地址:https://www.luogu.org/problemnew/show/P1196

 

Summarize:

  1. 此题为带权并查集,需要两个数组,每列长度由下标第一位根节点记录,另外一个数组记录每个节点在当前队列中所处位置;

  2. 只要注意 find 函数中位置的更新操作;

 

附代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<vector>
 7 #include<queue>
 8 #include<cmath>
 9 using namespace std;
10  
11 #define min(a,b) a>b?b:a;
12 #define LL long long
13 const int N = 3e4+5;
14 int T, f[N], line[N], pos[N];
15  
16 int find(int x)
17 {
18     if(x == f[x]) return x;
19      
20     int pre = f[x];
21     f[x] = find(f[x]);
22     pos[x] += pos[pre]-1;
23     return f[x];
24 }
25  
26 int main()
27 {
28     char option;
29     int a, b;
30      
31     ios::sync_with_stdio(false);
32      
33     cin>>T;
34     for(int i=1; i<N; i++)
35         line[i]=pos[i]=1, f[i]=i;
36     while(T--)
37     {
38         cin>>option>>a>>b;
39          
40         int sa = find(a);
41         int sb = find(b);
42          
43         if(option == 'M') {
44             if(sa != sb) {
45                 f[sa] = sb;
46                 pos[sa] += line[sb];
47                 line[sb] += line[sa];
48             }
49         }
50         else {
51             if(sa != sb) cout<<-1<<endl;
52             else cout<<abs(pos[a]-pos[b])-1<<endl;
53         }
54     }
55      
56     return 0;
57 }

 

posted @ 2018-08-03 11:05  liubilan  阅读(113)  评论(0编辑  收藏  举报