题意
- 还是
dijkstra
最短路径题,路的边权分两个,dist
和cost
,第一标尺是dist
最小,第二标尺是cost
最小,此时唯一。
注意
- 这道题还要输出路径,所以为每个点记录前驱,最后来一个递归输出。
代码
#include <iostream>
#include <algorithm>
#include <climits>
using namespace std;
const int Nmax = 500;
int N, M, S, D;
int dist[Nmax][Nmax];
int cost[Nmax][Nmax];
int m_dist[Nmax];
int m_cost[Nmax];
bool s[Nmax];
int v[Nmax];
void DIJKSTRA(int s0)
{
fill(m_dist, m_dist + Nmax, INT_MAX);
fill(s, s + Nmax, false);
m_dist[s0] = 0;
m_cost[s0] = 0;
for (int i = 0; i < N; i++)
{
int min = INT_MAX, k;
for (int j = 0; j < N; j++)
{
if (!s[j] && m_dist[j] < min)
{
min = m_dist[j];
k = j;
}
}
s[k] = true;
for (int j = 0; j < N; j++)
{
if (!s[j] && dist[k][j] != INT_MAX)
{
if (m_dist[k] + dist[k][j] < m_dist[j])
{
m_dist[j] = m_dist[k] + dist[k][j];
m_cost[j] = m_cost[k] + cost[k][j];
v[j] = k;
}
else if (m_dist[k] + dist[k][j] == m_dist[j] && m_cost[k] + cost[k][j] < m_cost[j])
{
m_cost[j] = m_cost[k] + cost[k][j];
v[j] = k;
}
}
}
}
}
void PRINT(int d)
{
if (d == S)
{
cout << d;
return;
}
PRINT(v[d]);
cout << " " << d;
}
int main()
{
cin >> N >> M >> S >> D;
int c1, c2;
fill(dist[0], dist[0] + Nmax*Nmax, INT_MAX);
for (int i = 0; i < M; i++)
{
cin >> c1 >> c2;
cin >> dist[c1][c2];
cin >> cost[c1][c2];
dist[c2][c1] = dist[c1][c2];
cost[c2][c1] = cost[c1][c2];
}
DIJKSTRA(S);
PRINT(D);
cout << " " << m_dist[D] << " " << m_cost[D];
return 0;
}