算法笔记--图
题目:PAT A1034
题解:
- 姓名---编号 stringtoint map<string,int>,inttostring map<int,string>
- 每个人的点权可以在读入的时候直接处理==边权之和
- 图的遍历分为两步 ::::先遍历联通快,在便利图
- 注意联通环 需要在递归进行遍历的时候先进性边权相加,在进行递归访问节点的问题
#include <iostream> #include <map> #include <string> using namespace std; const int maxn = 2100; const int INF = 10000000; map<int, string> inttostring; map<string, int> stringtoint; map<string, int> Gang; int G[maxn][maxn] = { 0 }, weight[maxn] = { 0 }; int n, k, numperson=0; bool vis[maxn] = { false }; //图有环,先累加编圈,在遍历节点,单个连通图的遍历 void dfs(int nowlist, int &head,int &number,int &totalvalue) { number++; vis[nowlist] = true; if (weight[nowlist] > weight[head]) { head = nowlist; } for (int i = 0; i < numperson; ++i) { if (G[nowlist][i] > 0) { totalvalue += G[nowlist][i]; G[nowlist][i] = G[i][nowlist] = 0; if (vis[i] == false) { dfs(i, head, number, totalvalue); } } } } //遍历整个图 获取每个联通快的信息 void dfstrave() { for (int i = 0; i < numperson; ++i) { if (vis[i] == false) { int head = i, num = 0, tot = 0; dfs(i, head, num, tot); if (num > 2 && tot > k) { Gang[inttostring[head]] = num; } } } } int change(string str) { if (stringtoint.find(str) != stringtoint.end()) return stringtoint[str]; else { stringtoint[str] = numperson; inttostring[numperson] = str; return numperson++; } } int main() { int w; string str1, str2; cin >> n >> k; for (int i = 0; i < n; ++i) { cin >> str1 >> str2 >> w; int id1 = change(str1); int id2 = change(str2); weight[id1] += w; weight[id2] += w; G[id1][id2] += w; G[id2][id1] += w; } dfstrave(); cout << Gang.size() << endl; for (auto i : Gang) cout << i.first << " " << i.second << endl; system("pause"); return 0;
}