洛谷 P1892 [BOI2003]团伙(种类并查集)

传送门

解题思路

用并查集f存朋友关系,一个数组e存的是敌人关系,是一个辅助数组,所以叫做种类并查集。

当p和q是朋友时,直接合并,但是当是敌人时,需要一些操作。

当p还没有敌人时(即p的敌人是自己),直接e[p]=q;

否则就把p的敌人和q变成朋友,这也就是变相把p和q变成敌人。

当然,对q也是如此。

最后统计有多少人是祖先,也就是说自己的朋友是自己,统计下来。

AC代码

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int maxn=1005;
 5 int f[maxn],e[maxn];
 6 int n,m;
 7 char c;
 8 int find(int x){
 9     if(f[x]==x) return x;
10     return f[x]=find(f[x]);
11 }
12 int ans;
13 int main(){
14     cin>>n>>m;
15     for(int i=1;i<=n;i++) f[i]=i,e[i]=i;
16     for(int i=1;i<=m;i++){
17         int p,q;
18         cin>>c>>p>>q;
19         if(c=='F'){
20             f[find(p)]=find(q);
21         }
22         else{
23             if(e[p]==p)e[p]=find(q);
24             else f[find(e[p])]=find(q);
25             if(e[q]==q)e[q]=find(p);
26             else f[find(e[q])]=find(p);
27         }
28     }
29     for(int i=1;i<=n;i++){
30         if(f[i]==i) ans++;
31     }
32     cout<<ans;
33     return 0;
34 }

 

posted @ 2019-08-23 21:04  尹昱钦  阅读(332)  评论(1编辑  收藏  举报