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

Posted Jack_the_Ripper

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1370: [Baltic2003]Gang团伙(luogu 1892)(种类并查集)相关的知识,希望对你有一定的参考价值。

题面:

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

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

题解:

  种类并查集。。

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

  因此,将每个点拆成两个点,一个是朋友点,另一个是敌人点。当读到A与B是朋友时,就将A与B所对应的朋友点并集;当读到两个点是敌人的时候,就将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;    
}

 

以上是关于BZOJ 1370: [Baltic2003]Gang团伙(luogu 1892)(种类并查集)的主要内容,如果未能解决你的问题,请参考以下文章

并查集BZOJ1370- [Baltic2003]Gang团伙

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

[bzoj1369] [Baltic2003]Gem

[bzoj1369][Baltic2003]Gem_树形dp_结论题

bzoj1369 [Baltic2003]Gem

bzoj 1367: [Baltic2004]sequence