784. 强盗团伙 AcWing

原题链接

考察:并查集的基本应用

想到了再建一个敌人数组,但没想到怎么操作...菜是原罪

正确思路:

       如果是朋友,我们直接并入一个集合

       如果是敌人,我们需要建立一个N叉树,分支是敌人数组的下标,里面的值是根,比如e[5] = 1,表示根为1,分支为5的树,n次操作后,我们会形成一个n叉树,此时我们需要将这些分支全部并入朋友数组,像上题的传染病的解法,将1号分支作为并入对象,每个分支依次与它合并,这样最后就会并入朋友数组中

 1 #include <iostream>
 2 using namespace std;
 3 const int N = 1010;
 4 int p[N],e[N],ans,vis[N];
 5 int find(int x)
 6 {
 7     if(p[x]!=x) p[x]=find(p[x]);
 8     return p[x];
 9 }
10 void merge(int x,int y)
11 {
12     p[find(p[x])] = find(y);
13 }
14 int main()
15 {
16     int n,m;
17     char op[2];
18     scanf("%d%d",&n,&m);
19     for(int i=1;i<=n;i++) p[i] = i;
20     while(m--){
21         int x,y;
22         scanf("%s%d%d",op,&x,&y);
23         if(op[0]=='E'){
24             if(!e[x]) e[x] = y;
25             if(!e[y]) e[y] = x;
26             merge(e[x],y);
27             merge(e[y],x);
28         }else merge(x,y);
29     }
30     for(int i=1;i<=n;i++){
31         if(!vis[find(i)]) ans++;
32         vis[find(i)] =1;
33     }
34     printf("%d\n",ans);
35     return 0;
36 }

 

posted @ 2021-01-03 12:27  acmloser  阅读(108)  评论(0编辑  收藏  举报