PAT(Advance)1087. All Roads Lead to Rome
该题分制为30分。
题目链接https://pintia.cn/problem-sets/994805342720868352/problems/994805379664297984
该题是多权路径,不仅要计算边权(最短路)还要计算点权,可以用Dijkstra+DFS,核心是有一个前驱数表。
题目要求在最短路的情况下,获得的happin最多,当获得happin一样时,平均每个城市的happiness最多。
还有一个注意点是题目给的城市都是字符串,我用map<string,int>,map<int,string>来做的,第一个用于存储时字符串查找编号,第二个是用于输出时编号查找字符串。
题目不算难,只要搞清楚条件就行了。
#include<iostream>
#include<map>
#include<vector>
using namespace std;
const int maxn = 210;
const int INF = 99999999;
map<string, int>m;
map<int, string>resm;
vector<int>pre[maxn];
vector<int>tempPath, path;
int G[maxn][maxn];
bool vis[maxn] = { false };
int d[maxn];
int n, k, x = 0;
float maxhappiness = 0, maxavghappiness = 0;
int w[maxn];
string st;
void Dijkstra(int s)
{
fill(d, d + maxn, INF);
d[s] = 0;
for (int i = 0; i < n; i++)
{
int u = -1, MIN = INF;
for (int j = 0; j < n; j++)
{
if (!vis[j] && d[j] < MIN)
{
MIN = d[j];
u = j;
}
}
if (u == -1) return;
vis[u] = true;
for (int v = 0; v < n; v++)
{
if (!vis[v] && G[u][v] != INF)
{
if (d[u] + G[u][v] < d[v])
{
d[v] = d[u] + G[u][v];
pre[v].clear();
pre[v].push_back(u);
}
else if (d[u] + G[u][v] == d[v])
{
pre[v].push_back(u);
}
}
}
}
}
void DFS(int v)
{
if (v == m[st])
{
x++;
tempPath.push_back(v);
float value = 0, avg = 0;
for (int i = 0; i < tempPath.size(); i++)
{
int id = tempPath[i];
value += w[id];
}
avg = value / (tempPath.size()-1);
if (value > maxhappiness)
{
maxhappiness = value;
maxavghappiness = avg;
path = tempPath;
}
else if (value == maxhappiness)
{
if (avg > maxavghappiness)
{
maxavghappiness = avg;
path = tempPath;
}
}
tempPath.pop_back();
}
tempPath.push_back(v);
for (int i = 0; i < pre[v].size(); i++)
{
DFS(pre[v][i]);
}
tempPath.pop_back();
}
int main()
{
fill(G[0], G[0] + maxn * maxn, INF);
cin >> n >> k >> st;
m[st] = 0;
resm[0] = st;
for (int i = 0; i < n-1; i++)
{
int weight;
string s;
cin >> s >> weight;
w[i+1] = weight;
m[s] = i+1;
resm[i+1] = s;
}
for (int i = 0; i < k; i++)
{
string s1, s2;
int dis;
cin >> s1 >> s2 >> dis;
G[m[s1]][m[s2]] = G[m[s2]][m[s1]] = dis;
}
Dijkstra(0);
DFS(m["ROM"]);
printf("%d %d %.0f %d\n", x, d[m["ROM"]], maxhappiness, (int)maxavghappiness);
for (int i = path.size()-1; i >=0 ; i--)
{
cout << resm[path[i]];
if (i > 0)
{
cout << "->";
}
}
return 0;
}