/*问题描述:
假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),
则认为他们属于同一个朋友圈,
请写程序求出这n个人里一共有多少个朋友圈。
假如:n = 5, m = 3, r = {{1 , 2} , {2 , 3} ,{4 , 5}},表示有5个人,1和2是好友,2和3是好友,4和5是好友,
则1、2、3属于一个朋友圈,4、5属于另一个朋友圈,结果为2个朋友圈。
最后请分析所写代码的时间、空间复杂度。评分会参考代码的正确性和效率。*/
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int N,M;
cin>>N>>M;
vector<int> friends(N,0);
for(int i=0;i<N;++i)//初始时每个人一个组
friends[i]=i;
vector< vector<int> > relationship(M,vector<int>(2,0));
int index=0;
while(index<M)
{//输入关系
int rea,reb;
cin>>rea>>reb;
relationship[index][0]=rea;
relationship[index][1]=reb;
index++;
}
for(int i=0;i<M;++i)
{
int a=friends[relationship[i][0]-1];
int b=friends[relationship[i][1]-1];
if(a==b)
continue;
else//合并分组,总是将大的分组替换为较小的分组
{
if(a<b)
{
for(int j=0;j<N;++j)
{
if(friends[j]==b)
friends[j]=a;
}
}
else
{
for(int j=0;j<N;++j)
{
if(friends[j]==a)
friends[j]=b;
}
}
}
}
int count=0;
for(int i=0;i<N;++i)
{//统计分组个数
cout<<friends[i]<<" ";
if(friends[i]==i)
count++;
}
cout<<endl<<count<<endl;
return 0;
}
#include<iostream>
#include<vector>
using namespace std;
//这个方法无法找出各个朋友圈的人
int find(int x,vector<int>& friends)
{
int result=x;
while(result!=friends[result])
{//找出相应的分组号
result=friends[result];
}
int reSet=x;
while(result!=friends[reSet])
{//将分组号重设
int tmp=friends[reSet];
friends[reSet]=result;
reSet=tmp;
}
return result;
}
void merge(int a,int b,vector<int>& friends)
{
int rea=find(a,friends);
int reb=find(b,friends);
if(rea==reb)
return;
if(rea<reb)//重设分组号
friends[b]=rea;
else
friends[a]=reb;
}
int main()
{
int N,M;
cin>>N>>M;
vector<int> friends(N,0);
for(int i=0;i<N;++i)//初始时每个人一个组
friends[i]=i;
vector< vector<int> > relationship(M,vector<int>(2,0));
int index=0;
while(index<M)
{//输入关系
int rea,reb;
cin>>rea>>reb;
relationship[index][0]=rea;
relationship[index][1]=reb;
index++;
}
for(int i=0;i<M;++i)
{
merge(relationship[i][0]-1,relationship[i][1]-1,friends);
}
int count=0;
for(int i=0;i<N;++i)
{//统计分组个数
cout<<friends[i]<<" ";
if(friends[i]==i)
count++;
}
cout<<endl<<count<<endl;
return 0;
}
并查集: