1. 程式人生 > 實用技巧 >238. 銀河英雄傳說

238. 銀河英雄傳說


帶權並查集:維護結點到其根結點的的一些資訊的並查集
本題維護的是每一個結點到它的根的距離

#include<iostream>
using namespace std;

const int N = 30010;

int p[N];
int d[N];
int cnt[N];

/*
    d[x]本身存放的是x到它的父節點的距離, 
    在經過一遍find之後需要將d[x]更新成x到它的根節點的距離
*/

int find(int x){
    if(p[x] != x){
        int root = find(p[x]);
        d[x] += d[p[x]];
        p[x] = root;
    }
    return p[x];
}

void merge(int x, int y){
    x = find(x), y = find(y);
    p[x] = y, d[x] = cnt[y];
    cnt[y] += cnt[x];
}

int main(){
    int T;
    
    cin >> T;
    
    for(int i = 1; i <= N; i ++) p[i] = i, cnt[i] = 1;
    
    while(T --){
        char op;
        int i, j;
        
        cin >> op >> i >> j;
        
        if(op == 'M') merge(i, j);
        else{
            int x = find(i), y = find(j);
            if(x != y) puts("-1");
            else cout << abs(d[i] - d[j]) - 1 << endl;
        }
    }
    
    return 0;
}