luogu P1892 [BOI2003]團伙
阿新 • • 發佈:2018-12-06
(在機房寫的題解就沒辦法放題目了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; }