题目大意:给出图的信息和出发点,求出到目的地的最短路径。如果最短路径有多条,输出总点权最大的一条。如果仍有多条,输出平均点权最大的一条。
常规的dijkstra + dfs问题,数据没有什么坑点,虽然时间限制200ms,但是由于数据量很少(200节点),不用什么优化措施也不会超时。
AC代码:
#include <vector>
#include <map>
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAXN = 210;
const int INF = 0x7FFFFFFF;
int G[MAXN][MAXN];
int d[MAXN];
int w[MAXN] = {0};
bool visited[MAXN] = {false};
vector<int> pre[MAXN];
map<string, int> nameToId;
map<int, string> idToName;
void dijkstra(int s, int N)
{
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(!visited[j] && d[j] < min)
{
u = j;
min = d[j];
}
}
if(u == -1) return;
visited[u] = true;
for (int k = 0; k < N; ++k)
{
if(G[u][k] < INF && !visited[k] && d[k] > d[u] + G[u][k])
{
d[k] = d[u] + G[u][k];
pre[k].clear();
pre[k].push_back(u);
}
else if(G[u][k] < INF && !visited[k] && d[k] == d[u] + G[u][k])
pre[k].push_back(u);
}
}
}
void dfs(int v, int s, int &cnt, vector<int> &tmp, vector<int> &ans, int &maxWeight, double &maxAvgWeight)
{
if(v == s)
{
cnt++;
tmp.push_back(v);
int sumWeight = 0;
for (int i = tmp.size() - 1; i >= 0; --i)
sumWeight += w[tmp[i]];
double avgWeight = sumWeight / (tmp.size() - 1);
if(sumWeight > maxWeight)
{
maxWeight = sumWeight;
maxAvgWeight = avgWeight;
ans = tmp;
}
else if(sumWeight == maxWeight && avgWeight > maxAvgWeight)
{
maxAvgWeight = avgWeight;
ans = tmp;
}
tmp.pop_back();
}
tmp.push_back(v);
for (int i = 0; i < pre[v].size(); ++i)
dfs(pre[v][i], s, cnt, tmp, ans, maxWeight, maxAvgWeight);
tmp.pop_back();
}
int getId(const string &name, int &cityCnt)
{
if(nameToId.find(name) != nameToId.end()) return nameToId[name];
nameToId[name] = cityCnt;
idToName[cityCnt] = name;
return cityCnt++;
}
int main()
{
fill(G[0], G[0] + MAXN * MAXN, INF);
int N, K;
char name[10];
scanf("%d%d%s", &N, &K, name);
int cityCnt = 0;
int S = getId(name, cityCnt);
for (int i = 0; i < N-1; ++i)
{
char city[10];
int weight;
scanf("%s%d", city, &weight);
int id = getId(city, cityCnt);
w[id] = weight;
}
for (int i = 0; i < K; ++i)
{
char city1[10], city2[10];
int dis;
scanf("%s%s%d", city1, city2, &dis);
int u = getId(city1,cityCnt), v = getId(city2, cityCnt);
G[u][v] = G[v][u] = dis;
}
int D = nameToId["ROM"];
dijkstra(S, N);
vector<int> tmp, ans;
int sumWeight = 0, cnt = 0;
double avgWeight = 0;
dfs(D, S, cnt, tmp, ans, sumWeight, avgWeight);
printf("%d %d %d %d\n", cnt, d[D], sumWeight, (int)avgWeight);
for (int i = ans.size() - 1; i >= 0; --i)
{
printf("%s", idToName[ans[i]].c_str());
if(i > 0) printf("->");
}
return 0;
}