You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
int n;//人数
|
|
|
|
|
int m;//关系数
|
|
|
|
|
char opt;//F: 代表 p 与 q 为朋友;E:代表 p 与 q 为敌人。
|
|
|
|
|
int p, q;//两个人员
|
|
|
|
|
int cnt;//最终的集合数量
|
|
|
|
|
//输出:一行一个整数代表最多的团体数
|
|
|
|
|
|
|
|
|
|
const int N = 1000 * 2 + 10;
|
|
|
|
|
//fa[i]表示i所属的集合,用fa[i+n]表示i所属集合的补集,实现的很巧妙,可以当成一个使用并查集的巧妙应用;
|
|
|
|
|
int fa[N]; //并查集数组,有时也写成 N << 1 ,从左到右,读作N左移1位,就是 2*N
|
|
|
|
|
|
|
|
|
|
//要深入理解这个递归并压缩的过程
|
|
|
|
|
int find(int x) {
|
|
|
|
|
if (fa[x] != x) fa[x] = find(fa[x]);
|
|
|
|
|
return fa[x];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//加入家族集合中
|
|
|
|
|
void join(int c1, int c2) {
|
|
|
|
|
int f1 = find(c1), f2 = find(c2);
|
|
|
|
|
if (f1 != f2)fa[f1] = f2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
测试用例:
|
|
|
|
|
6
|
|
|
|
|
4
|
|
|
|
|
E 1 4
|
|
|
|
|
F 3 5
|
|
|
|
|
F 4 6
|
|
|
|
|
E 1 2
|
|
|
|
|
|
|
|
|
|
答案:
|
|
|
|
|
3
|
|
|
|
|
*/
|
|
|
|
|
int main() {
|
|
|
|
|
//输入人数与关系数
|
|
|
|
|
cin >> n >> m;
|
|
|
|
|
|
|
|
|
|
//初始化并查集
|
|
|
|
|
for (int i = 1; i <= 2 * n; i++)fa[i] = i;
|
|
|
|
|
|
|
|
|
|
//输入关系
|
|
|
|
|
for (int i = 1; i <= m; i++) {
|
|
|
|
|
cin >> opt >> p >> q;
|
|
|
|
|
switch (opt) {
|
|
|
|
|
case 'E':
|
|
|
|
|
join(q + n, p);
|
|
|
|
|
join(p + n, q);
|
|
|
|
|
break;
|
|
|
|
|
case 'F':
|
|
|
|
|
join(p, q); //把p加入到q的家族中
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//找出最终的集合数量
|
|
|
|
|
for (int i = 1; i <= n; i++) if (fa[i] == i)cnt++;
|
|
|
|
|
//输出
|
|
|
|
|
cout << cnt << endl;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|