码迷,mamicode.com
首页 > 其他好文 > 详细

最短路径问题

时间:2017-05-06 11:51:03      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:最短路   svg   bae   llb   span   ret   生成   ==   png   

Dijkstra算法:有权图的单源最短路

技术分享

 

1.最短路必定只经过S中的顶点

  如果还存在一个w在S之外,v0>w必定小于v0>v,但路径是按照递增顺序生成的,那么w一定已经收录了,与前提矛盾。    

2.新收录一个v,会影响v的邻接点的dist值

  如果收录v使得s>w的路径变短,则s>w的路径一定经过v,并且v>w有一条边。如果v>w中间还存在顶点的话,该顶点一定在S之外(S是按递增顺序生成的,v刚被收录)而w的dist值为只经过S中的顶点。 dist[w] = min{dist[w], dist[v]+ <v, w>的权重}                                                                                                                             

3.过程

  1.从V-S中找到dist[i]最小的下标i,收录到S中

  2.更新与i的邻接点的dist值 

  3.V==S时停止

4.代码

 1 //邻接矩阵存储
 2 #define MaxVertexNum 1100
 3 struct GraphNode
 4 {
 5     int Nv;
 6     int Ne;
 7     int G[MaxVertexNum][MaxVertexNum];
 8 };
 9 typedef struct GraphNode *MGraph;
10 
11 Vertex FindMinDist(MGraph Graph, int dist[], int collected[])
12 {
13     Vertex MinV, V;
14     int MinDist = INFINITY;
15     
16     for (V = 0; V < Graph->Nv; V++) {
17         if (collected[V] == false && dist[V]<MinDist) //在未收录中找且dist[V]更小
18         {
19             MinDist = dist[V];
20             MinV = V;
21         }
22     }
23     if (MinDist < INFINITY)
24         return MinV;
25     else
26         return ERROR;
27 }
28 
29 bool Dijkstra(MGraph Graph, int dist[], int path[], Vertex s)
30 {
31     int collected[MaxVertexNum];
32     Vertex v, w;
33     
34     for (v = 0; v < Graph->Nv; v++) {
35         dist[v] = Graph->G[s][v];
36         if (dist[v] < INFINITY)
37             path[v] = s;
38         else
39             path[v] = -1;
40         collected[v] = false;
41     }
42     dist[v] = 0;
43     collected[s] = true;
44     
45     while (1) {
46         v = FindMinDist(Graph, dist, collected);
47         if (v == ERROR)
48             break;  //全收录完
49         collected[v] = true;
50         for (w = 0; w < Graph->Nv; w++) {
51             if (collected[w] == false && Graph->G[v][w]<INFINITY) {
52                 if (Graph->G[v][w] < 0)  //负值圈
53                     return false;
54                 if (dist[v]+Graph->G[v][w] < dist[w]) {
55                     dist[w] = dist[v] + Graph->G[v][w];
56                     path[w] = v;
57                 }
58             }
59         }
60     }
61     return true;
62 }

 

5.时间复杂度

 

  直接扫描所有未收录的顶点 T = O(|V|^2 + |E|)   稠密图效果好

  若用最小堆存取dist 读取最小的并更新堆O(log|V|), 但更新dist[w]的值需要插入最小堆O(log|V|)  T = O(|V|log|V| + |E|log|V|) = O(|E|log|V|)  稀疏图较好 (E和V同一个数量级,|V|log|V|比|V|^2要好)

 

若将单源最短路算法调用|V|遍,对于稠密图T = O(|V|^3 + |E||V|) 对于稀疏图较好

对于稠密图有Floyd算法 

Floyd算法:多源最短路算法

采用DP思想

技术分享为从技术分享技术分享的只以技术分享集合中的节点为中间节点的最短路径的长度。

  1. 若最短路径经过点k,则技术分享
  2. 若最短路径不经过点k,则技术分享

因此,技术分享

 1 //邻接矩阵存储
 2 
 3 bool Floyd(MGraph Graph, WeightType D[][MaxVertexNum], Vertex path[])
 4 {
 5     Vertex i, j, k;
 6     
 7     for (i = 0; i < Graph->Nv; i++)
 8     for (j = 0; j < Graph->Nv; j++) {
 9         D[i][j] = Graph->G[i][j];
10         path[i][j] = -1;
11     }
12     
13     for (k = 0; k < Graph->Nv; k++)
14         for (i = 0; i < Graph->Nv; i++)
15             for (j = 0; j < Graph->Nv; j++)
16                 if (D[i][k] + D[k][j] < D[i][j]) 
17                 {
18                     D[i][j] = D[i][k] + D[k][j];
19                     if (i == j && D[i][j] < 0)
20                         return false;
21                     path[i][j] = k;
22                 }
23     return true;
24 }

输出路径:

  递归输出, 先输出i到k,再输出k,再输出k到j路线。

时间复杂度

  T = O(|V|^3)

 

最短路径问题

标签:最短路   svg   bae   llb   span   ret   生成   ==   png   

原文地址:http://www.cnblogs.com/whileskies/p/6815998.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!