P1892 [BOI2003]团伙 并查集

Posted bxd123

tags:

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

题目描述

1920年的芝加哥,出现了一群强盗。如果两个强盗遇上了,那么他们要么是朋友,要么是敌人。而且有一点是肯定的,就是:

我朋友的朋友是我的朋友;

我敌人的敌人也是我的朋友。

两个强盗是同一团伙的条件是当且仅当他们是朋友。现在给你一些关于强盗们的信息,问你最多有多少个强盗团伙。

输入输出格式

输入格式:

 

输入文件gangs.in的第一行是一个整数N(2<=N<=1000),表示强盗的个数(从1编号到N)。 第二行M(1<=M<=5000),表示关于强盗的信息条数。 以下M行,每行可能是F p q或是E p q(1<=p q<=N),F表示p和q是朋友,E表示p和q是敌人。输入数据保证不会产生信息的矛盾。

 

输出格式:

 

输出文件gangs.out只有一行,表示最大可能的团伙数。

 

输入输出样例

输入样例#1: 复制
6
4
E 1 4
F 3 5
F 4 6
E 1 2
输出样例#1: 复制
3

维护敌人的敌人是朋友
技术图片
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
const int N=100000+5;
int f[N];
int find1(int x)
{
    return f[x]==x?x:f[x]=find1(f[x]);
}
struct node
{
    int x,y,v;
}s[N];
bool cmp(node a,node b)
{
    return a.v>b.v;
}
void union1(int x,int y)
{
    int a=find1(x);
    int b=find1(y);
    if(a!=b)
        f[a]=b;
}
int vis[N];
int main()
{
    int n,m;
    RII(n,m);
    rep(i,1,n)f[i]=i;
    char s[2];
    int a,b;
    rep(i,1,m)
    {
        RS(s);RII(a,b);
        if(s[0]==F)
            union1(a,b);
        else
        {
            if(!vis[a])vis[a]=b;
            else union1(vis[a],b);
            if(!vis[b])vis[b]=a;
            else union1(vis[b],a);
        }
    }
    int cnt=0;
    rep(i,1,n)
    if(f[i]==i)
        cnt++;
    cout<<cnt;

    return 0;
}
View Code

 






以上是关于P1892 [BOI2003]团伙 并查集的主要内容,如果未能解决你的问题,请参考以下文章

3/25《并查集》

[BOI2003]团伙

[洛谷P1892]团伙

并查集BZOJ1370- [Baltic2003]Gang团伙

BZOJ 1370 [Baltic2003]Gang团伙:并查集虚点

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