BOI2003 洛谷1892 (并查集入门)团伙

题目链接:[BOI2003]团伙 - 洛谷

首先对于两个人,如果是朋友关系的话,那么就直接用并查集并在一起就好了。但是如果是敌人关系那么在操作的时候就会复杂一点了,我们先使用一个数组来记录每个人的敌人有哪些,vis1[这个人的编号][第几个敌人] = 敌人的编号。那么我们在处理敌人关系的时候 ,例如a和b是敌人,那么就用并查集把a和b的所有敌人并在一起。再把b和a的所有敌人并在一起。最后再统计答案的时候就看看有多少人的fa[i] = i即为答案的数量。

code:

#include <bits/stdc++.h>
using namespace std;
int fa[1000010];
int vis1[1010][1000];
int fin(int x) {
    if(x != fa[x]) {
        return fa[x] = fin(fa[x]);  //并查集操作
    }
    return fa[x];
}
void unin(int x,int y) {   // 合并的操作
    x = fin(x);
    y = fin(y);
    fa[y] = x;
}
int a;
int b;
int cnt[100010];
int main() {
    cin>>a>>b;
    char qaq;
    int x,y;
    for(int i = 1;i <= a;i ++) {
        fa[i] = i;
    }
    for(int i = 1;i <= b;i ++) {
        cin>>qaq>>x>>y;
        if(qaq == 'F')
            unin(x,y);
        else {
            if(cnt[x])         // cnt用于记录这个人敌人的数量。
                for(int j = 1;j <= cnt[x];j ++)
                    unin(y, fin(vis1[x][j]));
            if(cnt[y])
                for(int j = 1;j <= cnt[y];j ++) {   //合并敌人的敌人
                    unin(x, fin(vis1[y][j]));
                }
            vis1[x][++ cnt[x]] = y;
            vis1[y][++ cnt[y]] = x;
        }
    }
    int ans = 0;
    for(int i = 1;i <= a;i ++) {
        if(fa[i] == i)   //统计答案
            ans ++;
    }
    cout<<ans;
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值