Description
艾斯蒂恩优公司最近打算推出一款社交网站,为了让更多用户之间互加好友,项目经理ZZK准备推出多度人脉功能。我们知道,人脉是我们直接的好友,那么多度人脉就是包括好友的好友以及好友的好友的好友等等,也就是除了直接好友之外能间接认识的所有好友。现在,ZZK给你网站数据库里所有的用户关系信息,希望你能将所有用户的多度人脉统计出来,并制作一个排行榜,看谁的多度人脉最多!
Input
第1行为该网站所有账户的个数n以及所有账户之间好友关系的个数m(1<=n<=4000,1<=m<=40000)
第2行到第m+1行为账户之间的好友关系,每行包括两个账户名,表示这两个账户互为好友,给定的数据不会有重复的关系(A B与B A是一个关系)。其中账户名最长为20个字符,全部为英文字母,账户名区分大小写。Output
输出n行,每行包括一个多度人脉数量,多度人脉从大到小进行排序。
Sample Input
6 5 SYC ZZK ZZK WC SYC WC SYC LG WZ LZCSample Output
2 1 1 0 0 0Hint
SYC的多度人脉为0
ZZK的多度人脉为1(LG)
WC的多度人脉为1(LG)
LG的多度人脉为2(ZZK、WC)
WZ的多度人脉为0
LZC的多度人脉为0
思路
关系不会重复,所以通过并查集合并彼此存在关系的人都会被存在一个树里,只要用树的总结点树减去个人所直接连接的人(包括自己)就得到了间接好友的数量。
思路是这样,但这个题有一个很大的坑点就是他的测试点存在自己可以是自己的好友的情况,一度让我WA到怀疑人生 ,下面是ac代码
#include<bits/stdc++.h>
using namespace std;
map<int,int>c;
map<string,int>d;
map<int,int>e;
int tr[4005];
int find(int a){
return tr[a]==a?tr[a]:tr[a]=find(tr[a]);
}
void hebing(int a,int b){
int f1=find(a);
int f2=find(b);
if(f1==f2){
return;
}
else{
e[f2]+=e[f1];
tr[f1]=f2;
}
}
string f[4005];
string s1[40005];
string s2[40005];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=4005;i++){
tr[i]=i;
}
int k=1;
for(int i=1;i<=m;i++){
cin>>s1[i]>>s2[i];
if(!d.count(s1[i])){
d.insert({s1[i],k});
f[k]=s1[i];
k++;
}
if(!d.count(s2[i])){
d.insert({s2[i],k});
f[k]=s2[i];
k++;
}
}
for(int i=1;i<=m;i++){
c[d[s1[i]]]++;
c[d[s2[i]]]++;
e[d[s1[i]]]=1;
e[d[s2[i]]]=1;
}
for(int i=1;i<=m;i++){
hebing(d[s1[i]],d[s2[i]]);
}
int sum[4005];
for(int i=1;i<k;i++){
// cout<<e[find(d[f[i]])]<<endl;
sum[i]=max(e[find(d[f[i]])]-c[d[f[i]]]-1,0);
}
sort(sum+1,sum+k,greater<int>());
for(int i=1;i<k;i++){
cout<<sum[i]<<endl;
}
return 0;
}