看CSDN上好像没有优化Dijkstra的题解,来水一发
思路
多了一个权值,不过因为是以路径短为第一条件,只要在路径相同的时候更新费用最小值即可。
一开始无限WA,看了十来遍都找不出问题,后来才知道输入有重边!只能用更加熟悉了Dijkstra来聊以自慰,不过也涨姿势了,以后题目没说明的话就判断有没有重边。
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
#define LL long long
const int MAXN = 1000 + 5;
const int INF = 0x3f3f3f3f;
struct POINT
{
int l, fee;
}mp[MAXN][MAXN];
int n, d[MAXN], f[MAXN];
typedef pair<int, int> pii;
priority_queue<pii, vector<pii>, greater<pii> > qu;
void Dijkstra(int st)
{
int i, j;
for (i = 0; i <= n; i++)
d[i] = f[i] = INF;
d[st] = f[st] = 0;
qu.push(make_pair(d[st], st));
while (!qu.empty())
{
pii u = qu.top();
qu.pop();
int x = u.second;
if (d[x] != u.first)
continue;
for (i = 1; i <= n; i++)
{
if (d[i] > d[x] + mp[x][i].l)
{
d[i] = d[x] + mp[x][i].l;
f[i] = f[x] + mp[x][i].fee;
qu.push(make_pair(d[i], i));
}
if (d[i] == d[x] + mp[x][i].l)
f[i] = min(f[i], f[x] + mp[x][i].fee);
}
}
}
int main()
{
//freopen("input.txt", "r", stdin);
int m, a, b, l, fee, i, j, st, ed;
while (scanf("%d%d", &n, &m), m + n)
{
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
{
mp[i][j].l = (i == j ? 0 : INF);
mp[i][j].fee = (i == j ? 0 : INF);
}
for (i = 0; i < m; i++)
{
scanf("%d%d%d%d", &a, &b, &l, &fee);
if (l < mp[a][b].l)
{
mp[a][b].l = mp[b][a].l = l;
mp[a][b].fee = mp[b][a].fee = fee;
}
else if (l == mp[a][b].l)
mp[a][b].fee = mp[b][a].fee = min(mp[a][b].fee, fee);
}
scanf("%d%d", &st, &ed);
Dijkstra(st);
printf("%d %d\n", d[ed], f[ed]);
}
return 0;
}