BZOJ 1370: [Baltic2003]Gang团伙(luogu 1892)(种类并查集)

题面:

  bzoj题面有误,还是看luogu的吧

  https://www.luogu.org/problemnew/show/P1892

题解:

  种类并查集。。

  因为有敌人的敌人是朋友这个条件,所以需要一个中转点。。

  因此,将每个点拆成两个点,一个是朋友点,另一个是敌人点。当读到A与B是朋友时,就将A与B所对应的朋友点并集;当读到两个点是敌人的时候,就将A点所对应的敌人点与B所对应的朋友点并集,将A所对应的朋友点和B所对应的敌人点并集。

  P.S.当读到A与B点是朋友时,不能将A与B点所对应的敌人结点并集,因为题目并没有说朋友的敌人是敌人。

代码:

#include<bits/stdc++.h>

using namespace std;

const int maxn=3010;
int fa[maxn],n,m,x,y,vis[maxn],ans;
char ch[3];

int ffa(int x){
    return fa[x]==x?x:fa[x]=ffa(fa[x]);    
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=2*n;i++) fa[i]=i;
    for(int i=1;i<=m;i++){
        scanf("%s%d%d",ch,&x,&y);
        if(ch[0]=='F'){
            int fx=ffa(x),fy=ffa(y);
            if(fx!=fy) fa[fy]=fx;
        }
        else{
            int fx=ffa(x),fy=ffa(y);
            int fxx=ffa(x+n),fyy=ffa(y+n);
            if(fx!=fyy) fa[fyy]=fx;
            if(fxx!=fy) fa[fxx]=fy;    
        }
    }
    for(int i=1;i<=n;i++)
        if(!vis[ffa(i)])
            ans++,vis[ffa(i)]=1;
    printf("%d",ans);
    return 0;    
}

 

转载于:https://www.cnblogs.com/tang666/p/8761484.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值