P1892 [BOI2003]团伙

原题链接

分析

从题目我们容易分析,这题是用并查集扩展域去写的。

可以通过两个限制条件,来得到两个式子

  • 朋友的朋友是我的朋友 <=> p[a]=b
  • 与我敌对的人有敌对关系的人,是我的朋友 <=> p[a+n]=b,p[b+n]=a;

易错点:这点给我卡成SB了,就是我一直认为p[a+n]=p[b+n]的,就是说,朋友的敌人也是我的敌人,其实是不一定的,朋友的敌人,不一定是我的敌人。这是和奇偶游戏很不相同的一大点,在奇偶游戏中,奇偶不相同,那就说明你跟我相反的一定是相同的。而奇偶相同,则说明相反的一定是相同的。

这里要着重说一下反集的概念,反集代表的是与当前集合性质相反的集合,只要把握住这一点去进行集合合并就不会出现奇怪的错误了。

AC_Code

#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int p[N*2];
bool st[N*2];
int n,m,res;

int find(int x)
{
    if(p[x]!=x) p[x]=find(p[x]);
    return p[x];
}

int main()
{
    cin>>n>>m;
    for(int i=1;i<=2*n;i++) p[i]=i;
    while(m--)
    {
        int a,b;
        char op;
        cin>>op>>a>>b;
        int pa = find(a+n),pb = find(b+n);
        a = find(a), b = find(b);
        if(op=='E') p[pa]=b,p[pb]=a;
        else p[a]=b;
    }
    for(int i=1;i<=n;i++){
        int x = find(i);
        if(!st[x]){
            //cout<<x<<endl;
            st[x]=1;
            res++;
        }
    }
    cout<<res<<endl;
    return 0;
}
posted @ 2021-11-11 20:04  艾特玖  阅读(59)  评论(0)    收藏  举报