单源最短路Dijstra算法
Posted 曹孟德
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单源最短路Dijstra算法相关的知识,希望对你有一定的参考价值。
Dijstra算法是寻找从某一顶点i出发到大其他顶点的最短路径。Distra算法的思想与Prim算法很像,它收录顶点的规则是按照路径长度递增的顺序收录的。设v0是源顶点,我们要寻找从v0出发到其他任意一点的最短路径。设已经求解的顶点(已经找到从v0出发到达该顶点最短路径的顶点)组成的集合是S={v0,v1,...vk};在收录下一个顶点v的时候要么是(v0,v),要么是(v0,vj,v);如果是后者,则一定有vj∈S,这一点很容易用反正法证明。Dijstra算法的时间复杂度是O(V^2),若是稀疏图改用邻接表存储,使用最小堆时间复杂度是O(ElogV).具体代码如下(这里假设图是连通的),有相应的解释:
1 #include<iostream> 2 using namespace std; 3 #define MAX_SIZE 100 4 #define MAX_NUMBER INT_MAX/2 5 struct Graph { 6 int V, E; 7 int w[MAX_SIZE][MAX_SIZE]; 8 }; 9 bool visit[MAX_SIZE]; 10 int dis[MAX_SIZE]; 11 int parent[MAX_SIZE]; 12 void Dijstra(Graph G, int i); //顶点i为出发点到其他点最短距离 13 void PrintPath(int j); 14 int main() { 15 int i, j,w,k; 16 Graph G; 17 for (i = 0; i < MAX_SIZE; i++) 18 for (j = 0; j < MAX_SIZE; j++) 19 G.w[i][j] = (i == j ? 0 :MAX_NUMBER); //对角线设置为0,其它设置为无穷 20 cin >> G.V >> G.E; 21 for (k=0; k< G.E; k++) { 22 cin >> i >> j >> w; 23 G.w[i][j] = G.w[j][i]=w; 24 } 25 Dijstra( G, 3); 26 for (i = 0; i < G.V; i++) 27 printf("%d %d\n",i, dis[i]); 28 PrintPath(6); //打印顶点6的路径 29 return 0; 30 } 31 void Dijstra(Graph G, int i) { 32 int k, j,pos,min; 33 memset(visit, 0, sizeof(visit)); //初始化 34 for (j = 0; j < G.V; j++) 35 dis[j] = MAX_NUMBER; //首先将距离都设置为无穷大 36 j = i; 37 dis[j] = 0; //到自身距离为0 38 parent[j] = -1; //i是父节点 39 visit[j] = 1; //首先将顶点i本身收录 40 for (i = 1; i < G.V; i++) { 41 for (k = 0; k < G.V; k++) { //更新上次收录的顶点j对其他顶点的影响 42 if (!visit[k] && dis[k]>=dis[j] + G.w[j][k]) {//这里G.w[j][k]在之前初始化不要设置为INT_MAX,否则dis[j]+G.w[j][k] 43 //可能会超过int的范围。 44 dis[k] = dis[j] + G.w[j][k]; 45 parent[k] = j; 46 } 47 } 48 pos = j, min =MAX_NUMBER; 49 for (k = 0; k < G.V; k++) { 50 if (!visit[k] && min>dis[k]) { 51 pos = k; 52 min = dis[k]; 53 } 54 } 55 j = pos; 56 visit[j] = 1; //将j收录 57 } 58 } 59 void PrintPath(int j) { 60 if (j== -1) 61 return; 62 PrintPath(parent[j]); 63 printf("%d ", j); 64 }
以上是关于单源最短路Dijstra算法的主要内容,如果未能解决你的问题,请参考以下文章