A1118 Birds in Forest (25 分| 并查集,附详细注释,逻辑分析)

写在前面

  • 思路分析
    • 1幅画里的鸟在同1棵树上,问有多少棵树和多少只鸟,及对于两只鸟判断是否在同1棵树上
    • 分析:
      • 使用并查集将1幅画中鸟使用Union函数合并在同1个集合里, cnt[i]数组保存以i为FindFather结点的集合⾥面鸟的个数
      • exist[i]表示鸟的id–i在输入的鸟的序号里面是否出现过,遍历cnt数组并累加所有不为0的个数即可得知有多少棵树,累加所有出现过的鸟的id的cnt的值即可得知鸟的个数
      • 判断两只鸟是否在同1棵树,只需要知道这两只鸟的findFather是否相等即可
  • 知识盲点,学习ing
    • 几个跟即几棵树

测试用例

  • input:
    4
    3 10 1 2
    2 3 4
    4 1 5 7 8
    3 9 6 4
    2
    10 5
    3 7
    output:
    2 10
    Yes
    No
    

ac代码

  • #include<iostream>
    using namespace std;
    
    int n, m, k;
    const int maxn = 10010;
    int fa[maxn] = {0}, cnt[maxn]= {0};
    int findFather(int x)
    {
        int a = x;
        while(x != fa[x])
            x = fa[x];
        while(a!=fa[a])
        {
            int z = a;
            a = fa[a];
            fa[z] = x;
        }
        return x;
    }
    void Union(int a, int b)
    {
    
        int faa = findFather(a);
        int fab = findFather(b);
        if(faa!=fab)
            fa[faa] = fab;
    }
    // 记录结点是否存在
    bool exist[maxn];
    int main()
    {
    
        scanf("%d", &n);
        for(int i = 1; i <= maxn; i++)
            fa[i] = i;
    
        int id, tmp, maxInx=0;
        for(int i = 0; i < n; i++)
        {
            scanf("%d%d", &k, &id);
            exist[id] = true;
            maxInx = max(maxInx,id);
            for(int j = 0; j < k-1; j++)
            {
                scanf("%d", &tmp);
                Union(id, tmp);
                exist[tmp] = true;
                maxInx = max(maxInx,tmp);
            }
        }
    
        // 将根节点映射到数组中
        for(int i = 1; i <= maxInx; i++)
        {
            if(exist[i] == true)
            {
                int root = findFather(i);
                cnt[root]++;
            }
        }
    
        int numTrees = 0, numBirds = 0;
        for(int i = 1; i <= maxInx; i++)
        {
            if(exist[i] == true && cnt[i] != 0)
            {
                numTrees++;
                numBirds += cnt[i];
            }
        }
    
        printf("%d %d\n", numTrees, numBirds);
        scanf("%d", &m);
        int ida, idb;
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d", &ida, &idb);
            printf("%s\n", (findFather(ida) == findFather(idb)) ? "Yes" : "No");
        }
        return 0;
    }
    
发布了328 篇原创文章 · 获赞 107 · 访问量 39万+

猜你喜欢

转载自blog.csdn.net/qq_24452475/article/details/100613197
今日推荐