原题地址
https://pintia.cn/problem-sets/1268384564738605056/problems/1286606445168746496
解题思路
加权无向图判断最短路问题,附加一个收费最小的优化条件。
在经典的Dijkstra算法上做一点点优化条件的改动就好~
参考代码
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
typedef double db;
typedef long long LL;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const int maxn = 510;
int n;
int cost[maxn][maxn], c[maxn];
//cost[v][u]表示从v到u的花费
//c[v]表示从源点s到v的最少花费
int d[maxn];
int G[maxn][maxn];
bool vis[maxn];
void Dijkstra(int s) { //s为源点
//初始化
fill(d, d + maxn, INF);
d[s] = 0;
fill(c, c + maxn, INF);
c[s] = 0;
//vis[s] = true;
/* for (int v = 0; v < n; v++) {
d[v] = G[v][s];
}*/
for (int i = 0; i < n; i++) { //执行n次
//找d最小值
int minN = INF, v = -1;
for (int j = 0; j < n; j++) {
if (!vis[j] && d[j] < minN) {
minN = d[j];
v = j;
//cout << "minD:" << v << endl;
}
}
if (v == -1) return; //未找到d最小的点,说明都已经访问了
vis[v] = true;
//对v的每个邻接点
for (int u = 0; u < n; u++) {
if (!vis[u] && G[u][v] != INF) {
//若v使得u路径变短
if (d[v] + G[v][u] < d[u]) {
d[u] = d[v] + G[v][u];
c[u] = c[v] + cost[v][u];
}
//若路径一样短,但是花费小,更新费用
else if (d[v] + G[v][u] == d[u] && c[v] + cost[v][u] < c[u]) {
c[u] = c[v] + cost[v][u];
}
}
}
}
}
int main() {
int m, start, last;
scanf("%d%d%d%d", &n, &m, &start, &last);
//初始化矩阵
fill(G[0], G[0] + maxn * maxn, INF);
for (int i = 0; i < n; ++i) {
G[i][i] = 0;
}
int s, l, dis, cos;
for (int i = 0; i < m; i++) {
scanf("%d%d%", &s, &l);
scanf("%d%d", &G[s][l], &cost[s][l]);
G[l][s] = G[s][l];
cost[l][s] = cost[s][l];
}
Dijkstra(start);
printf("%d %d", d[last], c[last]);
return 0;
}