一、题目链接
二、题目分析
(一)算法标签
最短路 Dijkstra
(二)解题思路
三、AC代码
解法一:
#include <iostream>
#include <cstring>
// 最短路(点数n, 边数m) m > n ^ 2 时为稠密图
// 一、单源最短路
// 1.所有边权都是正数
// 1)朴素Dijkstra算法 (O(n^2 + m))
// 2)堆优化版的Dijkstra算法 (O(mlogn))
// 2.存在负权边
// 1)Bellman-Ford (O(nm))
// 2)SPFA (一般O(m), 最坏O(nm))
// 二、多源(起点)汇(终点)最短路
// Floyd算法 (O(n^3))
// 无向图是一种特殊的有向图, 因此只用考虑有向图
using namespace std;
const int N = 510;
int n, m;
int g[N][N];
int dist[N];
bool st[N];
// 朴素Dijkstra算法:
// 1.dist[1] = 0, dist[i] = INF
// 2.for 0 ~ n:
// 1)t <- 不在s中且距离最近的点 (s为当前已确定最短距离的点的集合) for 1 ~ n
// 2)s <- t for 1 ~ n
// 3)用t更新其它点的距离
// 稠密图用邻接矩阵来存, 稀疏图用邻接表来存
int dijkstra() {
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;
for (int i = 0; i < n; i ++ ) {
int t = -1;
for (int j = 1; j <= n; j ++ ) {
if (!st[j] && (t == -1 || dist[j] < dist[t]))
t = j;
}
st[t] = true;
for (int j = 1; j <= n; j ++ ) {
dist[j] = min(dist[j], dist[t] + g[t][j]);
}
}
if (dist[n] == 0x3f3f3f3f) return -1;
return dist[n];
}
int main() {
cin >> n >> m;
memset(g, 0x3f, sizeof g);
while (m --) {
int x, y, z;
cin >> x >> y >> z;
g[x][y] = min(g[x][y], z); // 处理权值不一样的重边, 保留权值最小的边即可
}
cout << dijkstra();
return 0;
}