luogu1892 团伙(北京2003省选)
时空限制 1000ms/128MB
题目描述
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<iostream>
using namespace std;
const int N = 1005;
int father[N],a[N][N]={0};
int find(int x){
if (father[x]==x) return x;
else return father[x]=find(father[x]);
}
int main(){
ios::sync_with_stdio(false);
int n,m;
char F;
cin>>n>>m;
for (int i=1; i<=n; i++) father[i]=i;
for (int i=1,p,q,k1,k2; i<=m; i++){
cin>>F>>p>>q;
if (F=='F'){ //是朋友,合并
k1=find(p); k2=find(q); father[k2]=k1;
}
else { //是敌人,p的敌人些互为朋友,q的敌人些互为朋友
for (int j=1; j<=a[p][0]; j++){ //p的敌人些互为朋友,合并
k1=find(q); k2=find(a[p][j]); father[k2]=k1;
}
for (int j=1; j<=a[q][0]; j++){ //q的敌人些互为朋友,合并
k1=find(p); k2=find(a[q][j]); father[k2]=k1;
}
a[p][++a[p][0]]=q; //p的敌人数+1 保存p的第a[p][0]号敌人编号q
a[q][++a[q][0]]=p; //p的敌人数+1 保存q的第a[q][0]号敌人编号p
}
}
int ans=0;
for (int i=1; i<=n; i++)
if (father[i]==i) ans++;
cout<<ans<<endl;
return 0;
}