zoukankan      html  css  js  c++  java
  • P1892 [BOI2003]团伙

    题目传送门

    一、理解与感悟

    种类并查集的模板题。

    相关资料:
    https://zhuanlan.zhihu.com/p/97813717

    相关试题:
    https://www.cnblogs.com/littlehb/p/15111650.html

    二、完整代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int n;//人数
    int m;//关系数
    char opt;//F: 代表 p 与 q 为朋友;E:代表 p 与 q 为敌人。
    int p, q;//两个人员
    int cnt;//最终的集合数量
    //输出:一行一个整数代表最多的团体数
    
    const int N = 1000 * 2 + 10;
    //fa[i]表示i所属的集合,用fa[i+n]表示i所属集合的补集,实现的很巧妙,可以当成一个使用并查集的巧妙应用;
    int fa[N];    //并查集数组,有时也写成 N << 1 ,从左到右,读作N左移1位,就是 2*N
    
    //要深入理解这个递归并压缩的过程
    int find(int x) {
        if (fa[x] != x) fa[x] = find(fa[x]);
        return fa[x];
    }
    
    //加入家族集合中
    void join(int c1, int c2) {
        int f1 = find(c1), f2 = find(c2);
        if (f1 != f2)fa[f1] = f2;
    }
    
    /**
    测试用例:
    6
    4
    E 1 4
    F 3 5
    F 4 6
    E 1 2
    
    答案:
    3
    */
    int main() {
        //输入人数与关系数
        cin >> n >> m;
    
        //初始化并查集
        for (int i = 1; i <= 2 * n; i++)fa[i] = i;
    
        //输入关系
        for (int i = 1; i <= m; i++) {
            cin >> opt >> p >> q;
            switch (opt) {
                case 'E':
                    join(q + n, p);
                    join(p + n, q);
                    break;
                case 'F':
                    join(p, q);       //把p加入到q的家族中
                    break;
            }
        }
        //找出最终的集合数量
        for (int i = 1; i <=  n; i++) if (fa[i] == i)cnt++;
        //输出
        cout << cnt << endl;
        return 0;
    }
    
  • 相关阅读:
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
    Evanyou Blog 彩带
  • 原文地址:https://www.cnblogs.com/littlehb/p/15117190.html
Copyright © 2011-2022 走看看