计蒜客:网络交友:map+set+并查集

  在网络社交的过程中,通过朋友,也能认识新的朋友。在某个朋友关系图中,假定 A 和 B 是朋友,B 和 C 是朋友,那么 A 和 C 也会成为朋友。即,我们规定朋友的朋友也是朋友。

现在要求你每当有一对新的朋友认识的时候,你需要计算两人的朋友圈合并以后的大小。

 

 

 

解决思想:

路径压缩:只关心每个结点的父结点,而不关心树的真正结构,在一次查询过程中,把查找路径上的结点的父结点都设为根结点

1.set来存储人名字(实质上是用来人名去重,是一个辅助手段)

2.经过set去重,map来存储名字和编号num++

3.while循环里边输入边统计

 1 #include <iostream>
 2 #include <map>
 3 #include <set>
 4 using namespace std;
 5 int  pa[10010];//
 6 void init(){//每个元素都是一个集合,自己是自己的根结点
 7     for(int i=1;i<=10000;i++){
 8         pa[i]=i;
 9     }
10 }
11 int get(int x){//路径压缩思想查找
12     if(pa[x]==x){
13         return x;
14     }
15     return pa[x]=get(pa[x]);
16 }
17 int merge(int x,int y){
18     int fx=pa[x];
19     int fy=pa[y];
20     if(fx!=fy){
21         pa[fx]=fy;
22     }
23 }
24 int main(){
25     int n;
26     cin>>n;
27     set<string> name;
28     map<string,int> m;
29     int num=1;
30     init();
31     string a,b;
32     while(n--){
33         cin>>a>>b;
34         if(!name.count(a)){//名字a没出现过在name中
35             name.insert(a);
36             m[a]=num++;//先赋值后加1
37         }
38         if(!name.count(b)){//同上判断b
39             name.insert(b);
40             m[b]=num++;
41         }
42         merge(m[a],m[b]);//用map的编号 关联a,b
43         int res=0;
44         for(int i=1;i<num;i++){
45             if(get(i)==get(m[b]))//get时已经压缩路径,此处是从头查找和m[b]同一根结点的结点个数,并输出
46                 res++;
47         }
48         cout<<res<<endl;
49     }
50      return 0;  
51 }

 

posted @ 2020-08-04 20:00  nilbook  阅读(142)  评论(0编辑  收藏  举报