BZOJ 1370 团伙

两个认识的人不是朋友就是敌人,且满足:

1,朋友的朋友是朋友;

2,敌人的敌人是朋友。

一群朋友组成一个团伙,给出m个信息,求有多少个团伙。

用并查集,把一个点x拆成x和x’

若a与b为朋友,则将a与b所在集合合并,这样就满足朋友的朋友是朋友;

若a与b为敌人,则将a’与b所在集合合并,将a与b’所在集合合并;这样如果a与b,b与c为敌人,那么a与b’合并,b'与c合并,则a与c在同个集合,满足敌人的敌人是朋友。

最后,统计点1~n所属于的集合的个数即为答案。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 int fa[2010],a[2010],p,x,y,n,m,ans=0;
 5 void read(int &k){
 6     k=0; int f=1; char c=getchar();
 7     while (c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
 8     while ('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
 9     k*=f;
10 }
11 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
12 int main(){
13     read(n); read(m);
14     for (int i=1;i<=2*n;i++) fa[i]=i;
15     for (int i=1;i<=m;i++){
16         char c=getchar();
17         read(x); read(y);
18         if (c=='F') fa[find(x)]=find(y);
19         else{
20             fa[find(x)]=find(y+n);
21             fa[find(y)]=find(x+n);
22         }
23     }
24     for (int i=1;i<=n;i++) a[i]=find(i);
25     sort(a+1,a+n+1);
26     for (int i=1;i<=n;i++) if (a[i]!=a[i-1]) ans++;
27     printf("%d
",ans);
28     return 0; 
29 }
View Code
原文地址:https://www.cnblogs.com/DriverLao/p/7690557.html