利用并查集的思路将数据分成多个连通子图,并输出根结点即其权重:
#include<iostream>
#include<cstdio>
#include<string>
#include<map>
using namespace std;
const int N = 1000 + 10;
struct Relationship{
string name1, name2;
int time;
};
Relationship arr[N];
map<string, string> father; //每个成员的父亲结点
map<string, int> weight; //每个成员花费的总时间
map<string, int> sum; //用于记录一个团体的总时间
map<string, int> count; //用于记录一个团体的人数
map<string, int> ans; //最终结果
string Find(string x){
while(x != father[x]) x = father[x];
return x;
}
void Union(string x, string y){
string root1 = Find(x);
string root2 = Find(y);
if(root1 != root2){
if(weight[root1] > weight[root2]){
father[root2] = root1;
}else{
father[root1] = root2;
}
}
}
void Clear(){
father.clear();
weight.clear();
sum.clear();
count.clear();
ans.clear();
}
int main(){
int n, k;
while(scanf("%d%d", &n, &k) != EOF){
Clear();
for(int i = 0; i < n; i++){
cin>>arr[i].name1>>arr[i].name2>>arr[i].time;
weight[arr[i].name1] += arr[i].time;
weight[arr[i].name2] += arr[i].time;
father[arr[i].name1] = arr[i].name1;
father[arr[i].name2] = arr[i].name2;
}
for(int i = 0; i < n; i++) Union(arr[i].name1, arr[i].name2);
for(map<string, string>::iterator it = father.begin(); it != father.end(); it++){
string root = Find(it->first);
sum[root] += weight[it->first];
count[root]++;
}
for(map<string, int>::iterator it = count.begin(); it != count.end(); it++){
if(sum[it->first] > k * 2 && it->second > 2) //因为每个权重都加了两次,所以判断2k
ans[it->first] = it->second;
}
cout<<ans.size()<<endl;
for(map<string, int>::iterator it = ans.begin(); it != ans.end(); it++){
cout<<it->first<<" "<<it->second<<endl;
}
}
return 0;
}