在网络社交的过程中,通过朋友,也能认识新的朋友。在某个朋友关系图中,假定 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 }