您的位置:首页 > 其它

PAT 1034. Head of a Gang (30) 并查集

2018-01-14 01:20 441 查看
/*************************
题意:
并查集问题
要求出边长总量大于w,并且节点个数大于2的集合
/************************
求解思路和注意点:
用哈希来处理字符串与数组下标的绑定
注意点(坑点):
1.每个集合的father是自己定义的,但是输出时,必须输出入度值最大的节点。
************************/

/***********************
笔记:

*********************/
#include<iostream>
#include<stdio.h>
#include<string>
#include<vector>
#include<queue>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<stack>
#include<map>
using namespace std;
#define M 10001
#define INF 0x7fffffff
struct user{
string name;
string pw;
};

map<string,int> name;
int father[M];

int weight[M];
int num[M];
int sumweight[M];
int maxweight[M];
int selectw[M];
string getname[M];

bool cmp(int a,int b){
return getname[selectw[a]]<getname[selectw[b]];
}
int findfa(int kid){
int fa=kid;
if(father[kid] != kid){
fa=findfa(father[kid]);
father[kid]=fa;
}
return fa;
}

int main(){
int n,maxw,i,w;
string s1,s2;

int k=0;
cin>>n>>maxw;
for(i=0;i<n;i++){
father[i]=i;
weight[i]=0;
sumweight[i]=0;
num[i] = 1;
}

int fa1,fa2;
int n1,n2;
for(i=0;i<n;i++){
cin>>s1>>s2>>w;
if(name.find(s1)==name.end()){
getname[k]=s1;
name[s1]=k++;
}
if(name.find(s2)==name.end()){
getname[k]=s2;
name[s2]=k++;
}
n1=name[s1];
n2=name[s2];

fa1=findfa(n1);
fa2=findfa(n2);
if(fa1!=fa2){
father[fa1]=fa2;
num[fa2] += num[fa1];
num[fa1] = 0;
sumweight[fa2] += sumweight[fa1];
}
sumweight[fa2] += w;
weight[n1] += w;
weight[n2] += w;
if(maxweight[fa1] > maxweight[fa2]){
maxweight[fa2]=maxweight[fa1];
selectw[fa2]=selectw[fa1];
}
if(weight[n1] > maxweight[fa2]){
maxweight[fa2]=weight[n1];
selectw[fa2]=n1;
}
if(weight[n2] > maxweight[fa2]){
maxweight[fa2]=weight[n2];
selectw[fa2]=n2;
}
}

vector<int> vfa;
for(i=0;i<k;i++){
if(father[i]==i && sumweight[i]>maxw && num[i]>2)
vfa.push_back(i);
}
sort(vfa.begin(),vfa.end(),cmp);
printf("%d\n",vfa.size());
int fa,j;
for(i=0;i<vfa.size();i++){
fa=vfa[i];
cout<<getname[selectw[fa]]<<" "<<num[fa]<<endl;
}

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