1034 Head of a Gang
题目大意
根据对应的一对姓名和通话时长,合并成几簇,并筛选出符合条件的几簇。
算法思想
- 这道题看起来很简单,但是写起来真的麻烦,也可能是我没用并查集,导致出现一些致命的错误,最后花了很长时间去改
- 我的代码是在输入时就去创建簇,并添加到簇集合,主要是加入簇时比较麻烦,写了都有70行左右,需要找到已对应的簇,或者创建新的簇,或者合并新的簇(主要是这个难做),测试点4就需要合并
代码
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct node {
string name;
int weight;
};
struct cluster {
vector<node>mem;
int sum = 0, num = 0, head = 0;
};
vector<cluster>list;
bool cmp(cluster a, cluster b) {//比较函数
return a.mem[a.head].name < b.mem[b.head].name;
}
void add(string a, string b, int u) {//向簇中加元素
bool flag = false, flag1 = false, flag2 = false;
int wb=-1, wa=-1;
for (int i = 0; i < list.size(); i++) {//先遍历簇
for (int j = 0; j < list[i].mem.size(); j++) {//再遍历簇中的结点成员
if (list[i].mem[j].name == a || list[i].mem[j].name == b) {//在簇中找到已存在的相同元素
flag = true;
if (list[i].mem[j].name == a) {//找到a字符串时
list[i].mem[j].weight += u;//改变结点权重
if (list[i].mem[j].weight > list[i].mem[list[i].head].weight)//更新最大权重的head
list[i].head = j;
if (list[i].mem[j].weight == list[i].mem[list[i].head].weight && list[i].mem[j].name < list[i].mem[list[i].head].name)//更新字符串更小的head
list[i].head = j;
flag1 = true;
wa = i;
}
if (list[i].mem[j].name == b) {//找到b字符串
list[i].mem[j].weight += u;
if (list[i].mem[j].weight > list[i].mem[list[i].head].weight)
list[i].head = j;
if (list[i].mem[j].weight == list[i].mem[list[i].head].weight && list[i].mem[j].name < list[i].mem[list[i].head].name)
list[i].head = j;
flag2 = true;
wb = i;
}
}
}
}
if (!flag) {//没有找到对应的簇,创建新簇
cluster c;
node d, e;
d.name = a;
d.weight = u;
e.name = b;
e.weight = u;
c.mem.push_back(d);
c.mem.push_back(e);
c.num += 2;
c.sum += u;
list.push_back(c);
}
else {//找到对应簇
if (flag1 && flag2) {//a,b字符串都已对应
if (wa == wb) {//属于统一簇
list[wa].sum += u;
}
else {//不属于统一簇,需要合并簇
list[wa].num += list[wb].num;
list[wa].sum = list[wa].sum + list[wb].sum + u;
if (list[wa].mem[list[wa].head].weight < list[wb].mem[list[wb].head].weight)//更新head位置
list[wa].head += list[wb].head + 1;
list[wa].mem.insert(list[wa].mem.end(), list[wb].mem.begin(), list[wb].mem.end());//插入到list[wa]的mem后面
list.erase(list.begin() + wb);//删除wb位置
}
}
if (!flag1) {//没找到a字符串对应,但是b字符串已对应,将a加入到b簇中
list[wb].num++;
node d;
d.name = a;
d.weight = u;
list[wb].sum += u;
list[wb].mem.push_back(d);
}
if (!flag2) {//将b加入到a簇中
list[wa].num++;
node d;
d.name = b;
d.weight = u;
list[wa].sum += u;
list[wa].mem.push_back(d);
}
}
return;
}
int main() {
int n, k, u, m = 0;
string a, b;
cin >> n >> k;
for (int i = 0; i < n; i++) {
cin >> a >> b >> u;
add(a, b, u);//创建簇
}
sort(list.begin(), list.end(), cmp);//排序
for (int i = 0; i < list.size(); i++) {//找到合适的簇
if (list[i].sum > k && list[i].num>2)
m++;
}
cout << m << endl;
for (int i = 0; i < list.size(); i++) {
if(list[i].sum>k && list[i].num>2)
cout << list[i].mem[list[i].head].name << " " << list[i].num << endl;
}
return 0;
}