银河英雄传说 - 带权并查集
题目地址: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 }