算法基礎——連通塊中點的數量

原題連接ios

題目:spa

給定一個包含n個點(編號爲1~n)的無向圖,初始時圖中沒有邊。code

如今要進行m個操做,操做共有三種:ci

  1. 「C a b」,在點a和點b之間連一條邊,a和b可能相等;
  2. 「Q1 a b」,詢問點a和點b是否在同一個連通塊中,a和b可能相等;
  3. 「Q2 a」,詢問點a所在連通塊中點的數量;

輸入格式get

第一行輸入整數n和m。string

接下來m行,每行包含一個操做指令,指令爲「C a b」,「Q1 a b」或「Q2 a」中的一種。io

輸出格式stream

對於每一個詢問指令」Q1 a b」,若是a和b在同一個連通塊中,則輸出「Yes」,不然輸出「No」。數據

對於每一個詢問指令「Q2 a」,輸出一個整數表示點a所在連通塊中點的數量集合

每一個結果佔一行。

數據範圍

1 ≤ n, m ≤ 10^5

輸入樣例:

5 5
C 1 2
Q1 1 2
Q2 1
C 2 5
Q2 5

輸出樣例:

Yes
2
3

完整AC代碼

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 100010;
int p[N], cnt[N];

int n, m;

int findRoot(int x){
    if(p[x] != x) p[x] = findRoot(p[x]);
    return p[x];
}

int main(){
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        p[i] = i;
        cnt[i] = 1;
    }

    while(m --){
        string op;
        int a, b;
        cin >> op;
        if(op == "C"){
            scanf("%d%d", &a, &b);
            if(findRoot(a) != findRoot(b)){ //若是a,b不在同一集合內
                cnt[findRoot(b)] += cnt[findRoot(a)];
                p[findRoot(a)] = findRoot(b);
            }
        }
        else if (op == "Q1"){
            scanf("%d%d", &a, &b);
            if(findRoot(a) == findRoot(b)) puts("Yes");
            else puts("No");
        }
        else{
            scanf("%d", &a);
            printf("%d\n", cnt[findRoot(a)]);
        }
    }
    return 0;
}
相關文章
相關標籤/搜索