题目


解法1

点击查看代码
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;

vector<int> parent;

int findRoot(int x) {
    if (parent[x] != x) {
        parent[x] = findRoot(parent[x]); // 路径压缩
    }
    return parent[x];
}

void unionSets(int x, int y) {
    int rootX = findRoot(x);
    int rootY = findRoot(y);
    if (rootX != rootY) {
        parent[rootY] = rootX;
    }
}

int main() {
    int N;
    cin >> N;
    parent.resize(10001); // 鸟的编号最多到10000
    for (int i = 1; i <= 10000; ++i) {
        parent[i] = i; // 初始化父节点
    }

    unordered_set<int> birds; // 存储所有出现过的鸟的编号
    for (int i = 0; i < N; ++i) {
        int K;
        cin >> K;
        vector<int> pic(K);
        for (int j = 0; j < K; ++j) {
            cin >> pic[j];
            birds.insert(pic[j]);
        }
        for (int j = 1; j < K; ++j) {
            unionSets(pic[0], pic[j]); // 合并同一张照片中的鸟
        }
    }

    // 统计连通分量的数量
    unordered_set<int> roots;
    for (int bird : birds) {
        cout<<findRoot(bird)<<endl;
        roots.insert(findRoot(bird));
    }
    int treeCount = roots.size();
    int birdCount = birds.size();
    cout << treeCount << " " << birdCount << endl;

    int Q;
    cin >> Q;
    while (Q--) {
        int a, b;
        cin >> a >> b;
        if (findRoot(a) == findRoot(b)) { // 检查是否在同一集合
            cout << "Yes" << endl;
        } else {
            cout << "No" << endl;
        }
    }

    return 0;
}