一、思路
Dijkstra单元最短路径问题
核心代码:
for( int j = 0; j < N; ++j )
if( G[v][j] != INF && dist[v] + G[v][j] < dist[j] )//若存在路径,且从v出发更近
{
dist[j] = dist[v] + G[v][j];
cost[j] = cost[v] + C[v][j];
path[j] = v;
}
else if( G[v][j] != INF && dist[v] + G[v][j] == dist[j] && cost[v] + C[v][j] < cost[j] )//若存在路径,且从v出发距离与其原路径距离等同,但代价更低;
{
cost[j] = cost[v] + C[v][j];
path[j] = v;
}
二、代码
#include <cstdio>
#include <vector>
using namespace std;
#define INF 0x7FFFFFFF
int main()
{
int N, M, S, D;
scanf("%d %d %d %d", &N, &M, &S, &D);
vector<vector<int>> G(500, vector<int>(500, INF)), C(500, vector<int>(500, INF));
vector<int> visited(500, 0), dist(500, INF), path(500, -1), cost(500, INF), ans;
dist[S] = cost[S] = 0;
for( int i = 0, c1, c2, d, c; i < M; ++i )
{
scanf("%d %d %d %d", &c1, &c2, &d, &c);
G[c2][c1] = G[c1][c2] = d;
C[c1][c2] = C[c2][c1] = c;
}
for( int i = 0, v, min; i < N; ++i )
{
min = INF;
for( int j = 0; j < N; ++j )
if( !visited[j] && dist[j] < min )
{
v = j;
min = dist[j];
}
if( min == INF )
break;
visited[v] = 1;
for( int j = 0; j < N; ++j )
if( G[v][j] != INF && dist[v] + G[v][j] < dist[j] )
{
dist[j] = dist[v] + G[v][j];
cost[j] = cost[v] + C[v][j];
path[j] = v;
}
else if( G[v][j] != INF && dist[v] + G[v][j] == dist[j] && cost[v] + C[v][j] < cost[j] )
{
cost[j] = cost[v] + C[v][j];
path[j] = v;
}
}
for( int i = D; i != -1; i = path[i] )
ans.push_back(i);
for( int i = ans.size() - 1; i >= 0; --i )
printf("%d ", ans[i]);
printf("%d %d", dist[D], cost[D]);
}