您的位置:首页 > 其它

PAT甲题题解-1034. Head of a Gang (30)-并查集

2017-04-19 20:16 567 查看
给出n和k
接下来n行,每行给出a,b,c,表示a和b之间的关系度,表明他们属于同一个帮派
一个帮派由>2个人组成,且总关系度必须大于k。
帮派的头目为帮派里关系度最高的人。
(注意,这里关系度是看帮派里边的和,而不是帮派里所有个人的总和。
如果是按个人算的话,相当于一条边加了两次,所以应该是>2*k)
问你有多少个合格帮派,以及每个帮派里最大的头目是谁,按字典序输出

先并查集一下,然后统计每个帮的成员数、总关系度、以及头目

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <map>

using namespace std;
const int maxn=(1000+5)*2;
map<string,int> maps;
string id_name[maxn];
int rel[maxn]; //每个人的weight
int vis[maxn];
struct Gang{
string name;
int num;
int tot=0;
int maxweight=0;
bool operator<(const Gang tmp)const{
if(name.compare(tmp.name)<=0)
return true;
else
return false;
}
}gang[maxn];
//并查集
struct UF{
int fa[maxn];
int num[maxn];
void init(){
for(int i=0;i<maxn;i++){
fa[i]=i;
num[i]=1;
}
}
int find_root(int u){
if(fa[u]!=u)
fa[u]=find_root(fa[u]);
return fa[u];
}
void Union(int x,int y){
int fx=find_root(x);
int fy=find_root(y);
if(fx!=fy){
fa[fy]=fx;
num[fx]+=num[fy];
}
}
}uf;

int main()
{
char str1[20],str2[20];
int a;
int cnt=0;
int n,k;
uf.init();
memset(rel,0,sizeof(rel));
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++){
cin>>str1>>str2;
scanf("%d",&a);
if(maps[str1]==0){
maps[str1]=++cnt;
id_name[cnt]=str1;
}
if(maps[str2]==0){
maps[str2]=++cnt;
id_name[cnt]=str2;
}
rel[maps[str1]]+=a;
rel[maps[str2]]+=a;
uf.Union(maps[str1],maps[str2]);
}
memset(vis,0,sizeof(vis));
int gangcnt=0;
//父亲一样的属于同一个组,建立父亲id与帮派之间的映射
for(int i=1;i<=cnt;i++){
int group=uf.find_root(i);
if(!vis[group]){
vis[group]=++gangcnt;
gang[gangcnt].num=uf.num[group];
gang[gangcnt].tot+=rel[i];
gang[gangcnt].maxweight=rel[i];
gang[gangcnt].name=id_name[i];
}
else{
int id=vis[group];
gang[id].tot+=rel[i];
if(rel[i]>gang[id].maxweight){
gang[id].name=id_name[i];
gang[id].maxweight=rel[i];
}
}
}
sort(gang+1,gang+gangcnt+1);
int ans=0;
for(int i=1;i<=gangcnt;i++){
//tot要除以2,因为一条边的weight加了2次
if(gang[i].num>2&&gang[i].tot/2>k){

ans++;
}
}
printf("%d\n",ans);
for(int i=1;i<=gangcnt;i++){
if(gang[i].num>2&&gang[i].tot/2>k){
cout<<gang[i].name<<" "<<gang[i].num<<endl;
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: