AcWing 1608. 森林里的鸟 并查集

地址 https://www.acwing.com/solution/content/15062/

一些科学家为森林中成千上万的鸟类拍照。

假设所有出现在同一张照片中的鸟都属于同一棵树。

请你帮助科学家计算森林中树木的最大数量,对于任何一对鸟类,请判断它们是否在同一棵树上。

输入格式
第一行包含整数 N 表示照片数量。

接下来 N 行,每行描述一张照片,格式如下:

K B1 B2 … BK
K 表示照片中的鸟的数量,Bi 是鸟的具体编号。

保证所有照片中的鸟被连续编号为 1 到某个不超过 104 的整数。

再一行包含整数 Q。

接下来 Q 行,每行包含两个鸟的编号,表示一组询问。

输出格式
第一行输出最大可能的树的数量以及鸟的数量。

接下来对于每个询问,如果被询问的两个鸟在同一棵树上,则在一行中输出 Yes,否则输出 No。

数据范围
1≤N≤104,
1≤K≤10,
1≤Q≤104
输入样例:
4
3 10 1 2
2 3 4
4 1 5 7 8
3 9 6 4
2
10 5
3 7
输出样例:
2 10
Yes
No

算法1
并查集裸题
考察对并查集原理和操作。

询问完所有数据后,在一棵树上的鸟的编号可以使用并查集合并。
鸟的编号是1~n,那么输入的最大编号就是鸟的数目
树的数目其实就是1~n中并查集的种类
根据并查集的定义,f[1]~f[n]中 f[i]!=i 就说明他和别人在同一个并查集里
那么我们只要统计 f[i]==i的个数 就是并查集的集合数目也就是题目中树的数目

C++ 代码

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;


const int N = 10010;

int f[N];
int cnt[N];

void init() {
    for (int i = 1; i < N; i++) {
        f[i] = i;
        cnt[i] = 1;
    }
}

int find(int x) {
    return f[x] == x ? x : f[x] = find(f[x]);
}

int n, m;

vector<int> v[N];
int uni[N];
int maxNum = -1;

int main()
{
    cin >> n;
    init();
    for (int i = 0; i < n; i++) {
        int num = 0;
        cin >> num;
        for (int j = 0; j < num; j++) {
            int t;cin >> t;
            maxNum = max(t, maxNum);
            v[i].push_back(t);
        }
        for (int j = 0; j < v[i].size() - 1; j++) {
            int a = v[i][j]; int b = v[i][j + 1];
            a = find(a); b = find(b);
            if (a != b) {
                f[a] = b;
                cnt[b] += cnt[a];
            }
        }
    }

    int ans = 0;
    for (int i = 1; i <= maxNum; i++) {
        int idx = find(i);
        uni[idx]++;
    }

    for (int i = 1; i <= maxNum; i++) {
        if (uni[i] != 0) ans++;
    }
    cout << ans << " "<< maxNum << endl;

    cin >> m;

    for (int i = 0; i < m; i++)
    {
        int a, b;
        cin >> a >> b;

        if (find(a) == find(b)) {
            cout << "Yes" << endl;
        }
        else {
            cout << "No" << endl;
        }
    }

    return 0;
}

 

posted on 2020-06-20 16:57  itdef  阅读(196)  评论(0编辑  收藏  举报

导航