Dijkstra单源最短路径
问题描述
输入
n
表示n个结点,m
表示m条边,求编号1
的结点到每个点的最短路径输出从第一个点到第n个点的最短路径
思路
-
将图
g[][]
中所有的权值初始化为0x3f
表示正无穷 -
将
dist[]
中所有的值初始化为0x3f
表示从第一个点到所有点的距离默认为无穷 -
将
dist[1]
设置为0
表示从第一个点到它自己距离为零 -
执行
n
(也就是处理n
个点的次数)次如下操作:-
找到所有没有确定最短路径的点中,离
1
点(初始点)最近的那个例如: 下面这个图,第一次找到结点
1
,因为它没有被确定过最短路径, 然后更新到达2
的路径为新的最短路为2,到达3的最短路为4。
-
#include <iostream>
#include <cstring>
using namespace std;
const int N = 510;
int g[N][N], dist[N]; //g为邻接矩阵
bool st[N]; //表示结点是否已经确定最短路径
int n, m; //n为结点数量,m为边数量
int Dijkstra() {
memset(dist, 0x3f, sizeof dist);
dist[1] = 0; //从第一个结点到达第一个结点的最短路径为 0
for (int i = 0; i < n; i++ ) { //循环 n 次处理 n 个结点
int t = -1;
for (int j = 1; j <= n; j++ ) {
if (!st[j] && (t == -1 || dist[j] < dist[t])) { //第一次会选择找到的第一个边然后去找最短的边
t = j; //寻找没有确定最短路径的点当中 到第一个点最近的点
}
}
//找到没有确定的最近的点
for (int j = 1; j <= n; j++) {
dist[j] = min(dist[j], dist[t] + g[t][j]);
}//从第一个最近的点开始向后更新最短路径
st[t] = true; //将确定好最短路径的点设置为true表示已经确定了最短路径
}
return dist[n];
}
//测试数据:
/*
3 3
1 2 2
1 3 4
2 3 1
*/
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
memset(g, 0x3f, sizeof g);
while (m -- ) {
int u, v, c;
cin >> u >> v >> c;
g[u][v] = c; //无重边的情况,如果有重边需要进行取重边的最小值
}
int t = Dijkstra();
cout << t << endl;
}