PAT甲级1118Birds in Forest

题目链接

https://pintia.cn/problem-sets/994805342720868352/problems/994805354108403712

题解

题目要求

  • 输入
    • N:正整数,不超过1000,照片的数量
    • N张照片:每张照片中有K只鸟,鸟的索引从1开始,不超过10000。假设一张图片中出现的所有鸟属于同一棵树
    • Q:正整数,不超过10000,查询的数量
    • Q个查询
  • 输出
    • 有多少颗树、多少只鸟
    • 判断Q对鸟是否属于同一颗树

解题思路

代码

// Problem: PAT Advanced 1118
// URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805354108403712
// Tags: 并查集 路径压缩

#include <iostream>
using namespace std;

const int MAXN = 10001;
int tree[MAXN];
int birdNum[MAXN];

int findTree(int x){
    return (x == -1 || x == tree[x]) ? x : tree[x] = findTree(tree[x]);
}

void UNION(int a, int b){
    int ta = findTree(a), tb = findTree(b);
    if (ta != tb)
        tree[tb] = ta;
}

int main()
{
    fill(tree, tree + MAXN, -1);
    int n, q, k, bird1, bird2;
    scanf("%d", &n);
    for (int i = 0; i < n; i++){
        scanf("%d", &k);
        scanf("%d", &bird1);
        if (tree[bird1] == -1)
            tree[bird1] = bird1; // 记录该鸟
        for (int j = 1; j < k; j++){
            scanf("%d", &bird2);
            if (tree[bird2] == -1)
                tree[bird2] = bird2; // 记录该鸟
            UNION(bird1, bird2);
        }
    }

    int tempTree;
    for (int i = 0; i < MAXN; i++){
        tempTree = findTree(i);
        if (tempTree != -1){
            birdNum[tempTree] += 1;
        }
    }
    int treeCount = 0, birdCount = 0;
    for (int i = 0; i < MAXN; i++){
        if (birdNum[i] > 0){
            treeCount += 1;
            birdCount += birdNum[i];
        }
    }
    printf("%d %d
", treeCount, birdCount);
    scanf("%d", &q);
    int tree1, tree2;
    while (q--){
        scanf("%d%d", &bird1, &bird2);
        tree1 = findTree(bird1);
        tree2 = findTree(bird2);
        if (tree1 != -1 && tree2 != -1 && tree1 == tree2)
            printf("Yes
");
        else
            printf("No
");
    }
    return 0;
}

作者:@臭咸鱼

转载请注明出处:https://www.cnblogs.com/chouxianyu/

欢迎讨论和交流!


原文地址:https://www.cnblogs.com/chouxianyu/p/13841590.html