团伙 |
难度级别:C; 运行时间限制:1000ms; 运行空间限制:51200KB; 代码长度限制:2000000B |
试题描述
|
在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1、我朋友的朋友是我的朋友; 2、我敌人的敌人是我的朋友; 3、每个人都只有一个敌人。 所有是朋友的人组成一个团伙。告诉你关于这n个人的m条信息,即某两个人是朋友,或者某两个人是敌人,请你编写一个程序,计算出这个城市最多可能有多少个团伙? |
输入
|
第1行为n和m,N小于1000,M小于5000; 以下m行,每行为p x y,p的值为F或E,p为F时,表示x和y是朋友,p为E时,表示x和y是敌人。
|
输出
|
一个整数,表示这n个人最多可能有几个团伙。
|
输入示例
|
6 4 E 1 4 F 3 5 F 4 6 E 1 2 |
输出示例
|
3
|
其他说明
|
样例提示:{1},{2,4,6},{3,5}
|
用并查集解决“朋友问题”,再另开一个数组解决“敌人问题”。
#include<iostream> using namespace std; int n,m,a,b,pre[100001],ans;
int tmp[100001]; //表示数组的元素与数组下标是敌人
bool vis[100001]; char ch; int find(int x) { int t=x; if(pre[t]!=t) pre[t]=find(pre[t]); return pre[t]; } void join(int x,int y) { int tx=find(x),ty=find(y); pre[tx]=ty; return; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) pre[i]=i; for(int i=1;i<=m;i++) { cin>>ch>>a>>b; if(ch=='F') join(a,b); else { if(!tmp[a]) tmp[a]=b; else join(tmp[a],b); if(!tmp[b]) tmp[b]=a; else join(tmp[b],a);
//如果数组中没有元素,就把对方的元素存入,否则就与对方的敌人相互连接。 } } for(int i=1;i<=n;i++) { if(!vis[find(i)]) {ans++;vis[find(i)]=1;} } printf("%d",ans); //system("pause"); }