65 lines
1.5 KiB
C++
65 lines
1.5 KiB
C++
#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;
|
||
} |