考察Dijkstra算法
题目大意:
N个城市,M条无向边,需要从某个给定的起始城市出发,前往ROM。
除起始城市,每个城市都有一个幸福值(点权)
给出每条边的花费(边权)
求从起始城市出发,到达城市ROM所需要的最少的花费,并输出最少花费的路径(第一标尺)
如果有多条,选择幸福值最大的那条(第二标尺)
如果还有多条,选择平均幸福值最大的那条(第三标尺)
考虑DFS+Dijkstra方法,标尺情况已经在大意中列出
选择最短路径
numPath++;
int tempW = 0;
for (int i = tempPath.size() - 2; i >= 0; i--) {
int id = tempPath[i];
tempW += weight[id];
}
double tempAvg = 1.0 * tempW / (tempPath.size() - 1);
if (tempW > maxW) {
maxW = tempW;
maxAvg = tempAvg;
path = tempPath;
}
else if (tempW == maxW && tempAvg >= maxAvg) {//点权相同,平均点权更大
maxAvg = tempAvg;
path = tempPath;
}
AC代码:
//1087 All Roads Lead to Rome (30 分)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>'
using namespace std;
const int maxn = 210;
const int inf = 0x3fffffff;
int n, m, st, G[maxn][maxn], weight[maxn];
int d[maxn], numPath = 0, maxW = 0;
double maxAvg = 0;
bool vis[maxn] = { false };
vector<int> path, tempPath, pre[maxn];
map<string, int>cityToIndex;
map<int, string>indexToCity;
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] == false && d[j] < MIN) {
u = j;
MIN = d[j];
}
}
if (u == -1)return;
vis[u] = true;
for (int v = 0; v < n; v++) {
if (vis[v] == false && 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 == st) {
tempPath.push_back(v);
numPath++;
int tempW = 0;
for (int i = tempPath.size() - 2; i >= 0; i--) {
int id = tempPath[i];
tempW += weight[id];
}
double tempAvg = 1.0 * tempW / (tempPath.size() - 1);
if (tempW > maxW) {
maxW = tempW;
maxAvg = tempAvg;
path = tempPath;
}
else if (tempW == maxW && tempAvg >= maxAvg) {
maxAvg = tempAvg;
path = tempPath;
}
tempPath.pop_back();
return;
}
tempPath.push_back(v);
for (int i = 0; i < pre[v].size(); i++) {
dfs(pre[v][i]);
}
tempPath.pop_back();
}
int main() {
string start, city1, city2;
cin >> n >> m >> start;
cityToIndex[start] = 0;
indexToCity[0] = start;
st = 0;//起点编号为0;
for (int i = 1; i < n; i++) {
cin >> city1 >> weight[i];
cityToIndex[city1] = i;
indexToCity[i] = city1;
}
fill(G[0], G[0] + maxn * maxn, inf);
for (int i = 0; i < m; i++) {
cin >> city1 >> city2;
int c1 = cityToIndex[city1];
int c2 = cityToIndex[city2];
cin >> G[c1][c2];
G[c2][c1] = G[c1][c2];
}
dijkstra(0);
int rom = cityToIndex["ROM"];
dfs(rom);
printf("%d %d %d %d\n", numPath, d[rom], maxW, (int)maxAvg);
for (int i = path.size() - 1; i >= 0; i--) {
cout << indexToCity[path[i]];
if (i > 0)cout << "->";
}
return 0;
}