Note
- 图的遍历
- DFS
- 注意分辨边权与点权!!!本道题就是利用点权。
- 数组不能只开到1010,会出现段错误…
- ans记得排序。按字母表顺序可以用:
bool compare(string a, string b) {
return a + b < b + a;
}
Code
#include<bits/stdc++.h>
using namespace std;
struct node{
int id,weight;
node(int i,int w){
id=i;
weight=w;
}
};
int n,k,index_=1;
map<string,int> toId;
map<int,string> toName;
vector<int> v[2010];
vector<node> vn,ans;
int weight[2010];
bool visit[2010]={false};
bool cmp(node a,node b){
return a.weight>b.weight;
}
bool cmp_alpha(node a,node b){
return toName[a.id]+toName[b.id]<toName[b.id]+toName[a.id];
}
int NameToId(string s){
if(toId[s]==0) toId[s]=index_++;
return toId[s];
}
void dfs(int root){
visit[root]=true;
vn.push_back(node(root,weight[root]));
for(int i=0;i<v[root].size();i++){
if(visit[v[root][i]]==false)
dfs(v[root][i]);
}
return ;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("data.txt","r",stdin);
#endif
memset(weight,0,sizeof(weight));
int id1,id2,t;
string s1,s2;
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++){
cin>>s1>>s2>>t;
id1=NameToId(s1);
id2=NameToId(s2);
toName[id1]=s1;
toName[id2]=s2;
v[id1].push_back(id2);
v[id2].push_back(id1);
weight[id1]+=t;
weight[id2]+=t;
}
for(int i=1;i<index_;i++){
if(visit[i]==false){
int sum=0;
vn.clear();
dfs(i);
sort(vn.begin(),vn.end(),cmp);
for(int i=0;i<vn.size();i++){
sum+=vn[i].weight;
}
if(vn.size()>2&&sum>2*k){
ans.push_back(node(vn[0].id,vn.size()));
}
}
}
printf("%d\n",ans.size());
sort(ans.begin(),ans.end(),cmp_alpha);
for(int i=0;i<ans.size();i++){
printf("%s %d\n",toName[ans[i].id].c_str(),ans[i].weight);
}
return 0;
}