和1003题类似,只不过需要记录更多信息,由于我的1003题的解法已经包含了这些信息,因此只需要将城市名用map映射到对应的数字,就可以用那一题的代码。
#include<cstdio>
#include<queue>
#include<map>
#include<string>
#include<iostream>
using namespace std;
const int maxn = 202;
const int inf = 1000000000;
int happyness[maxn];
int road[maxn][maxn];
int visit[maxn], cost[maxn];
vector<int> before[maxn];
vector<int> q, remenber;
int maxTeam = 0, projectNum = 0;
string startSTR, aimSTR = "ROM";
int start;
map<string, int> mp;
void DFS(int aim) {
if (aim == start) {
projectNum++;
int totalTeam = 0;
for (int i = 0; i < q.size(); i++) {
totalTeam += happyness[q[i]];
}
if (totalTeam > maxTeam) {
maxTeam = totalTeam;
remenber = q;
}
return;
}
for (int i = 0; i < before[aim].size(); i++) {
q.push_back(before[aim][i]);
DFS(before[aim][i]);
q.pop_back();
}
return;
}
int main() {
int N, K, aim;
cin >> N >> K >> startSTR;
mp[startSTR] = start = 0;
happyness[start] = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (i == j) road[i][i] = 0;
else road[i][j] = inf;
}
}
for (int i = 0; i < N; i++) {
visit[i] = inf;
cost[i] = inf;
};
int c1, c2, length;
string city1, city2;
for (int i = 1; i < N; i++) {
cin >> city1 >> c1;
mp[city1] = i;
happyness[i] = c1;
if (city1 == "ROM") aim = i;
}
for (int i = 0; i < K; i++) {
cin >> city1 >> city2 >> length;
c1 = mp[city1];
c2 = mp[city2];
road[c1][c2] = length;
road[c2][c1] = length;
}
visit[start] = 0;
int smaller = start, m = inf;
bool done = false;
for (int k = 0; k < N; k++) {
for (int i = 0; i < N; i++) {
if (i == smaller) continue;
if (road[smaller][i] + visit[smaller] < cost[i]) {
cost[i] = road[smaller][i] + visit[smaller];
before[i].clear();
before[i].push_back(smaller);
}
else if (road[smaller][i] + visit[smaller] == cost[i]) {
before[i].push_back(smaller);
}
}
if (done == true) break;
smaller = -1, m = inf;
for (int i = 0; i < N; i++) {
if (visit[i] == inf && cost[i] < m) {
m = cost[i];
smaller = i;
}
}
visit[smaller] = cost[smaller];
if (smaller == aim) done = true;
}
q.push_back(aim);
DFS(aim);
printf("%d %d %d %d\n", projectNum, cost[aim], maxTeam, maxTeam / (remenber.size() - 1));
vector<int>::reverse_iterator it;
map<string, int>::iterator mpit;
int x;
for (x = remenber.size() - 1; x > 0; x--) {
for (mpit = mp.begin(); mpit != mp.end(); mpit++) {
if (mpit->second == remenber[x]) {
cout << mpit->first << "->";
break;
}
}
}
cout << "ROM" << endl;
return 0;
}