Dijkstra算法是单源最短路径算法;利用的是贪心思想,每次选择当前的最靠近源点的顶点确定为最短路径(所以Dijkstra算法需要满足的是所有边的权值都为正值,所以Dijkstra不能处理负边权问题)。
算法思路:
1. 将所有点分为两部分:已知最短路径顶点和未知最短路径顶点,先将源点加入已知最短路径,利用book[]存储。
2. 初始化各顶点的最短路径,有源点直接相连的点设置为边的权值,没有直接相连的点设置为无穷大;
3. 在所有未知最短路径的顶点中寻找距离最小的将其确定为最短路径,并对这点的所有出边进行松弛操作;
4. 重复3操作,直到所有点确定最短路径;
代码:
#include <string.h> #include<iostream> #include<vector> #include<queue> #define _Max 200020 #define INF 1<<30 using namespace std; int main() { int e[10][10],dis[_Max],book[_Max]; int n,m,s,t,w; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i==j) e[i][j]=0; else e[i][j]=INF; } } cin>>n>>m; for(int i=0;i<m;i++){ cin>>s>>t>>w; e[s][t]=w; } //初始化1号顶点到其他顶点的距离 for(int i=1;i<=n;i++){ dis[i]=e[1][i]; } //初始化book数组,1表示已求得最短路径,0表示未知最短路径 for(int i=1;i<=n;i++){ book[i]=0; } book[1]=1; int min,u; //dijkstra算法核心语句 for(int i=1;i<n;i++){//每次可以求得一个顶点的最短路径,通过n-1轮即可全部求出 //找到距离源点最远的未知最短路径的点,则这点可以确定为最短路径 min=INF; for(int j=1;j<=n;j++){ if(book[j]!=1&&dis[j]<min){ min=dis[j]; u=j; } } book[u]=1; for(int k=1;k<=n;k++){ if(e[u][k]<INF&&book[k]==0){ if(dis[k]>dis[u]+e[u][k]) dis[k]=dis[u]+e[u][k]; } } } for(int i=0;i<=n;i++){ cout<<dis[i]<<endl; } return 0; }
输入示例:
6 9
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
输出示例:
0
1
8
4
13
17
Dijstra算法为什么不能处理负边权问题?
例如:有三条边 1 3 8, 1 2 9, 2 3 -2;
由于Dijstra算法贪心思想,会先确定3号顶点的最短路径为8,但是因为有负边1-2-3的路径权值为7,所以当有负边是Dijstra算法不再适用;
原文地址:https://www.cnblogs.com/zdl2234/p/10360613.html
时间: 2024-11-29 07:15:03