(在机房写的题解就没办法放题目了www
(只能放链接 orz
emmmmm
是一道(蛮简单的 并查集
就是如何记录朋友或敌人的关系
题解里有一个反集的思想非常有意思(其实是我好不容易才理解23333
我们拿样例为例看一下吧
6
4
E 1 4
F 3 5
F 4 6
E 1 2
反集的实现过程是这样的
if(ch == 'E'){ fa[get(p + n)] = get(q); fa[get(q + n)] = get(p); }
首先 f[7] = 4;
然后正常的并集 f[3] = 5 f[4] = 6
再次 f[get(7)] = 2
此时get(7) = 4
那么 f[4] = 2
此时 2,4,6 为一个团伙
3,5 为一个团伙
1 单独一人
总共 3 个团伙
(反集太精彩了!!!
那么上代码
#include<cstdio> #include<iostream> using namespace std; #define maxn 1010 #define maxm 5010 int fa[maxn],w[maxm]; int get(int x){ if(fa[x] == x)return x; else return fa[x] = get(fa[x]); } int main(){ int n,m; scanf("%d%d",&n,&m); for(int i = 1;i <= n * 2;i++) fa[i] = i; for(int i = 1;i <= m;i++){ char ch; int p,q; cin >> ch >> p >> q; if(ch == 'F') fa[get(p)] = fa[get(q)]; if(ch == 'E'){ fa[get(p + n)] = get(q); fa[get(q + n)] = get(p); } } int ans = 0; for(int i = 1;i <= n;i++) if(fa[i] == i)//看有几个根即为有几个团伙 ans++; printf("%d",ans); return 0; }