求连通分量
1.dfs
2.并查集
用并查集的时候,因为接下来可能还会更新通话分钟数u,我又不想把对应的一类存储再进行判断......所以就在合并时进行判断操作,寻找最大的点(pre) 实时更新 只需要确保更新完后后续的也一并压入即可。
4 5测试点没过 暂时不清楚哪里遇到问题了
#include<iostream>
#include<cstdio>
#include<map>
#include<vector>
#include<set>
#include<algorithm>
using namespace std;
const int N = 4000+5;
map<string, int> a;
string Nm[N];
int Sum[N];
int Tot[N];
int pre[N];
struct Node {
string Head;
int Total, Num;
Node() {
Head="";
Total = 0;
Num = 0;
}
};
int cmp(Node a, Node b) {
return a.Head < b.Head;
}
map<int, Node> ans;
int n, k, id = 1;
vector<Node> V;
bool flag[N];
set<string> S;
void init() {
for(int i=0; i<=N; i++) {
pre[i] = i;
Tot[i] = 0;
Sum[i] = 0;
flag[i] = false;
}
}
int Find(int x) {
return x == pre[x] ? x : (pre[x] = Find(pre[x]));
}
bool Union(int a, int b) {
if(Find(a) == Find(b)) { //不需要合并
b = Find(b);
if(Sum[a] > Sum[b]) {
pre[b] = a;
pre[a] = a;
for(int i=0; i<id; i++)Find(i);
}
return false;
} else {
int ta = Find(a);
int tb = Find(b);
if(Sum[ta] < Sum[a]) {
pre[a] = a;
pre[ta] = a;
}
if(Sum[tb] < Sum[b]) {
pre[b] = b;
pre[tb] = b;
}
if(max(Sum[ta], Sum[a]) > max(Sum[tb], Sum[b])) {
pre[b] = pre[a];
} else
pre[a] = pre[b];
for(int i=0; i<id; i++)Find(i);
return true;
}
}
int main() {
init();
cin >> n >> k;
string s1, s2;
int tmp, cnt = n;
for(int i=0; i<n; i++) {
cin >> s1 >> s2 >> tmp;
/* S.insert(s1);
S.insert(s2);
*/
if(a[s1] == 0) {
Nm[id] = s1;
a[s1] = id++;
}
if(a[s2] == 0) {
Nm[id] = s2;
a[s2] = id++;
}
Sum[a[s1]] += tmp;
Sum[a[s2]] += tmp;
if(Union(a[s1], a[s2])) {
cnt --;
}
}
for(int i=1; i<id; i++) {
tmp = pre[i];
// cout << pre[i] << ":" << Nm[]<< endl;
// cout << tmp << "所对应的名字:" << Nm[tmp] << ":" << i << "duiy"<< Sum[i] <<"befsor" << ans[tmp].Total<< endl;
ans[tmp].Head = Nm[tmp];
ans[tmp].Total += Sum[i];
// cout << tmp << "所对应的名字:" << Nm[tmp] << ":" << i << "duiy"<< Sum[i] <<"after" << ans[tmp].Total<< endl;
ans[tmp].Num++;
}
for(map<int, Node>::iterator it=ans.begin(); it!=ans.end(); it++) {
if(it->second.Total > 2*k && it->second.Num>2) {
V.push_back(it->second);
}
}
cout << V.size() << endl;
sort(V.begin(), V.end(), cmp);
for(int i=0; i<V.size(); i++) {
cout << V[i].Head << " " << V[i].Num << endl;
}
return 0;
}