这一题看到要求连通分量的个数,我就不由自主夫人向并查集上靠,但是最后发现求完了连通分量的个数之后还有很多工作没做,而且也不好穿插其中。。。还是要设置更多的结构,以找出head,计算对应的weight.
借鉴柳婼大神代码:https://blog.csdn.net/liuchuo/article/details/52291920
两个点记录一下:一是用cin接收string要#include<string>。
二是vs2008因编译器的问题仿佛无法识别auto,所以对于map的遍历可以这样进行:
#include <map>
using namespace std;
map<string, int> ans;
map<string,int>::iterator it;
int main(){
for(it = ans.begin(); it != ans.end(); it++)
cout << it->first<< " " << it->second<< endl;
}
很关键,防止机考中无法编译。
下面是完整代码:
#include <iostream>
#include <string>
#include <map>
using namespace std;
map<string, int> stringToInt;
map<int, string> intToString;
map<string, int> ans;
map<string,int>::iterator it;
int idNumber = 1, k;
int stoifunc(string s) {
if(stringToInt[s] == 0) {
stringToInt[s] = idNumber;
intToString[idNumber] = s;
return idNumber++;
} else {
return stringToInt[s];
}
}
int G[2010][2010], weight[2010];
bool vis[2010];
void dfs(int u, int &head, int &numMember, int &totalweight) {
vis[u] = true;
numMember++;
if(weight[u] > weight[head])
head = u;//查找最大权值
for(int v = 1; v < idNumber; v++) {
if(G[u][v] > 0) {
totalweight += G[u][v];
G[u][v] = G[v][u] = 0;//遍历过一条边之后就把这条边的权值设为0
if(vis[v] == false)
dfs(v, head, numMember, totalweight);
}
}
}
void dfsTrave() {
for(int i = 1; i < idNumber; i++) {
if(vis[i] == false) {
int head = i, numMember = 0, totalweight = 0;
dfs(i, head, numMember, totalweight);
if(numMember > 2 && totalweight > k)
ans[intToString[head]] = numMember;//ans中一个键值对对应一个head-weight
}
}
}
int main() {
int n, w;
cin>>n>>k;
string s1, s2;
for(int i = 0; i < n; i++) {
cin>>s1>>s2>>w;
int id1 = stoifunc(s1);
int id2 = stoifunc(s2);
weight[id1] += w;
weight[id2] += w;
G[id1][id2] += w;
G[id2][id1] += w;
}
dfsTrave();
cout << ans.size() << endl;
for(it = ans.begin(); it != ans.end(); it++)
cout << it->first<< " " << it->second<< endl;
system("pause");
return 0;
}