题意:成员A与成员B通话 ,成员B与成员C通话,则 ABC即为一个团伙,一共有若干个团伙,每个团伙的人数大于2且相互通话时间超过一定值即为黑帮,每个黑帮伙里有一个BOSS,boss是与各个成员打电话最多的那一个,找出所有黑帮boss跟与之相应成员数,按字典序排列。
分析:通话姓名是字符串,不好直接构图,离散化一下,在用并查集确定团伙,在查找黑帮与BOSS
#include<stdio.h> #include<iostream> #include<algorithm> #include<stack> #include<map> #include<string> using namespace std; int bossLen[2099]; int oneLen[2099]; int Link[2099]; int n,K; map<string,int>mm1; // 字符串对应数字 map<int,string>mm2;//数字对应字符串 int f[2099]; int point[2099]; int index=0; struct data{ string name; int linkN; }node[2099]; int headNum=0; int find(int n){ if(f[n]==-1)return n; return f[n]=find(f[n]); } int um(int a,int b){ int fa=find(a),fb=find(b); if(fa==fb)return 0; else f[fa]=fb; } void init(){ int i; for(i=1;i<=2009;i++){ bossLen[i]=0; oneLen[i]=0; } for(i=0;i<=2009;i++){ f[i]=-1; } string str1,str2; for(i=1;i<=n;i++){ cin>>str1; int ll,rr; if(mm1.find(str1)==mm1.end()){ index++; mm1[str1]=index; mm2[index]=str1; ll=index; }else{ ll=mm1[str1]; } cin>>str2; if(mm1.find(str2)==mm1.end()){ index++; mm1[str2]=index; mm2[index]=str2; rr=index; }else{ rr=mm1[str2]; } int temp; scanf("%d",&temp); bossLen[ll]+=temp; bossLen[rr]+=temp; oneLen[ll]+=temp; um(ll,rr); } } int cmp(data x,data y){ return x.name<y.name; } void cal(){ int i; int useground[2099]; int hash1[2099]; int groundLen[2099]; int hashLen[2099]; for(i=1;i<=index;i++){ useground[i]=0; Link[i]=0; point[i]=find(i); hash1[i]=0; hashLen[i]=0; } for(i=1;i<=index;i++){ hash1[point[i]]++; } for(i=1;i<=index;i++){ hashLen[point[i]]+=oneLen[i]; Link[i]=hash1[point[i]]; } for(i=1;i<=index;i++){ groundLen[i]=hashLen[point[i]]; if(Link[i]>2&&groundLen[i]>K){ if(useground[point[i]]==1)continue;//该团伙遍历过,就不要遍历了 headNum++; int rk,max=0,k; for(k=1;k<=index;k++){//找团队中单人最多通话,就是老大 if(point[i]!=point[k])continue; if(bossLen[k]>max){ max=bossLen[k]; rk=k; } } useground[point[rk]]=1; node[headNum].linkN=Link[rk]; node[headNum].name=mm2[rk]; } } printf("%d ",headNum); sort(&node[1],&node[headNum+1],cmp); for(i=1;i<=headNum;i++){ cout<<node[i].name<<" "<<node[i].linkN<<endl; } } int main() { while(scanf("%d%d",&n,&K)!=EOF){ int i; init(); cal(); } return 0; }