• P1892 [BOI2003]团伙


    类似于食物链那道题,使用一个大小为2*n的并查集,对于第 i (1<=i<=n)个人,其朋友域是get(i),敌人域是get(i+n).

    若x与y是朋友,则merge(x,y).题意并没有说明朋友的敌人是敌人,所以不需要合并x,y的敌人域.

    若x与y是敌人,即x进入y的敌人域,y进入x的敌人域,merge(x, y + n), merge(y, x + n).

    重点强调这里的merge要写成如下形式:

    void merge(int x, int y) { fa[get(y)] = fa[get(x)]; }

    即把y"挂"在x上.

    既然集合内元素都是具有等价关系的,为什么反过来不可以呢?因为这道题目涉及到统计集合数量的问题.在处理完所有的合并操作后需要给出以1~n编号的人总共组成了多少个集合,如果把第 i 个人"挂"到了j + n上面,实践表明这和正确做法产生的总集合数量是相等的,但是我没有想到此时统计结果的有效方法.

    至此,还需要处理"敌人的敌人是朋友",实际上已经不需要额外处理了,在执行敌人合并时:

    假设有a,b,c三人,已知a与c敌对,b与c敌对,那么处理a,c的关系时,把c+n挂到a上,把a+n挂到c上:(一列表示一个集合)

       a     b     c     a+n     b+n     c+n

    c+n         a+n

    现在处理b,c的关系,把c+n(所在的集合)挂到b上,把b+n挂到c上:

       a     b     c     a+n     b+n     c+n

              a    a+n

       c+n  b+n

    会发现a和b自动合并到了一起,他们现在是朋友关系了.

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    int fa[2010], n, m;
    
    int get(int x) {
        if (fa[x] == x) return x;
        return fa[x] = get(fa[x]);
    }
    void merge(int x, int y) { fa[get(y)] = fa[get(x)]; }
    
    int main() {
        cin >> n >> m;
        for (int i = 1; i <= 2 * n; i++) fa[i] = i;
    
        while (m--) {
            char ch;
            int x, y;
            cin >> ch >> x >> y;
            if (ch == 'F')
                merge(x, y);
            else
                merge(x, y + n), merge(y, x + n);
        }
    
        int ans = 0;
        for (int i = 1; i <= n; i++)
            if (fa[i] == i) ans++;
        cout << ans << endl;
    
        return 0;
    }
    P1892

    做并查集的题目总是得要想着它内部的实现,因为它根本就没有接口,没有封装,STL没有它.

  • 相关阅读:
    mysql设置外网访问
    c# 导出excel的两种常见方法
    mysql记录
    nginx配置文件nginx.conf简单介绍
    nginx编译安装之-./configure 参数详解
    Springboot中Filter的使用
    Spring Boot中@ConditionalOnProperty使用详解
    spring boot2 配置 FastJsonHttpMessageConverter 不起作用
    springBoot yaml属性配置文件使用详解
    Eclipse离线安装Java Decompiler插件(反编译)
  • 原文地址:https://www.cnblogs.com/Gaomez/p/14376121.html
Copyright © 2020-2023  润新知