题目大意:给出图的信息,每条边的边权有两个,一是distance, 二是 cost,求出从起点到目的地的最短路径,如果最短路径有多条,输出 cost 最小的一条。
常规的dijkstra + dfs解法。
AC代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAXN = 510;
const int INF = 0x7FFFFFFF;
int G[MAXN][MAXN] = {0};
int d[MAXN] = {0};
int cost[MAXN][MAXN] = {0};
bool visited[MAXN] = {false};
vector<int> pre[MAXN];
void dijkstra(int s, int N)
{
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(!visited[k] && G[u][k] < INF && d[u] + G[u][k] < d[k])
{
d[k] = d[u] + G[u][k];
pre[k].clear();
pre[k].push_back(u);
}
else if(!visited[k] && G[u][k] < INF && d[u] + G[u][k] == d[k])
pre[k].push_back(u);
}
}
}
vector<int> path, tmpPath;
int optDis = INF, optCost = INF;
void dfs(int v, int s)
{
if(v == s)
{
tmpPath.push_back(v);
int dis = 0, cos = 0;
for (int i = tmpPath.size() - 1; i >= 1; --i)
{
dis += G[tmpPath[i]][tmpPath[i-1]];
cos += cost[tmpPath[i]][tmpPath[i-1]];
}
if(cos < optCost)
{
optDis = dis;
optCost = cos;
path = tmpPath;
}
tmpPath.pop_back();
return;
}
tmpPath.push_back(v);
for (int i = 0; i < pre[v].size(); ++i)
{
dfs(pre[v][i], s);
}
tmpPath.pop_back();
}
int main()
{
fill(G[0], G[0] + MAXN * MAXN, INF);
fill(d, d + MAXN, INF);
int N, M, S, D;
cin >> N >> M >> S >> D;
for (int i = 0; i < M; ++i)
{
int u, v, l, w;
scanf("%d%d%d%d", &u, &v, &l, &w);
G[u][v] = G[v][u] = l;
cost[u][v] = cost[v][u] = w;
}
dijkstra(S, N);
dfs(D, S);
for (int i = path.size() - 1; i >= 0; --i)
{
printf("%d ", path[i]);
}
printf("%d ", optDis);
printf("%d", optCost);
return 0;
}