最短路径问题
来源:互联网 发布:小战雅思 下载mac 编辑:程序博客网 时间:2024/06/08 06:09
问题描述:在网络中,求两个不同顶点之间的所有路径中,边的权值之和最小的那一条路径。
问题分类:
1单源最短路径问题:从某固定源出发求其到所有其他顶点的最短路径。
(1)无权图:
按照递增顺序找出到各个顶点的最短路径
//使用邻接表存储 dist[]和path[]全部初始化为-1typedef struct GNode *PtrToGNode;typedef struct Vnode { PtrToAdjVNode FirstEdge; DataType Data;//顶点数据} AdjList[MaxVertexNum];//AdjList邻接表类型struct GNode { int Nv;//顶点数 int Ne;//边数 AdjList G;//邻接表};typedef PtrToGNode LGraph;typedef struct AdjVNode *PtrToAdjVNode;struct AdjVNode { Vertex AdjV;//邻接表下标 WeightType Weight;//边权重 PtrToAdjVNode Next;};void Unweighted(LGraph Graph, int dist[], Vertex S) { Queue Q; Vertex V; PtrToAdjVNode W; Q = CreateQueue(Graph->Nv);//创建空队列,MaxSize为外部定义的常数 dist[S] = 0; AddQ(Q, S); while(!IsEmpty(Q)) { V = DeleteQ(Q); for(W=Graph->G[V].FirstEdge; W; W=W->Next) { if(dist[W->AdjV]==-1) {//w->adjv未被访问过 dist[W->AdjV] = dist[V]+1;//w->adjv到s的距离更新 path[W->AdjV] = V; AddQ(Q, W->AdjV); } } }}
(2)有权图的单源最短路径
这里主要讨论没有负值圈的图。使用Dijkstra算法:
令S={源点s + 已经确定了最短路径的顶点vi},对于任一未被收录的顶点V,定义dist[v]为s到v的最 短路径长度,但该路径仅经过S中的顶点。即路径 {s->(v
typedef struct GNode *PtrToGNode;struct GNode{ int Nv; int Ne; WeightType G[MaxVertexNum][MaxVertexNum]; Datatype Data[MaxVertexNum];};typedef PtrToGNode MGraph;//以邻接矩阵存储的图类型Vertex FindMinDist( MGraph Graph, int dist[], int collected[] ){ /* 返回未被收录顶点中dist最小者 */ Vertex MinV, V; int MinDist = INFINITY; for (V=0; V<Graph->Nv; V++) { if ( collected[V]==false && dist[V]<MinDist) { /* 若V未被收录,且dist[V]更小 */ MinDist = dist[V]; /* 更新最小距离 */ MinV = V; /* 更新对应顶点 */ } } if (MinDist < INFINITY) /* 若找到最小dist */ return MinV; /* 返回对应的顶点下标 */ else return ERROR; /* 若这样的顶点不存在,返回错误标记 */}bool Dijkstra( MGraph Graph, int dist[], int path[], Vertex S ){ int collected[MaxVertexNum]; Vertex V, W; /* 初始化:此处默认邻接矩阵中不存在的边用INFINITY表示 */ for ( V=0; V<Graph->Nv; V++ ) { dist[V] = Graph->G[S][V]; if ( dist[V]<INFINITY ) path[V] = S; else path[V] = -1; collected[V] = false; } /* 先将起点收入集合 */ dist[S] = 0; collected[S] = true; while (1) { /* V = 未被收录顶点中dist最小者 */ V = FindMinDist( Graph, dist, collected ); if ( V==ERROR ) /* 若这样的V不存在 */ break; /* 算法结束 */ collected[V] = true; /* 收录V */ for( W=0; W<Graph->Nv; W++ ) /* 对图中的每个顶点W */ /* 若W是V的邻接点并且未被收录 */ if ( collected[W]==false && Graph->G[V][W]<INFINITY ) { if ( Graph->G[V][W]<0 ) /* 若有负边 */ return false; /* 不能正确解决,返回错误标记 */ /* 若收录V使得dist[W]变小 */ if ( dist[V]+Graph->G[V][W] < dist[W] ) { dist[W] = dist[V]+Graph->G[V][W]; /* 更新dist[W] */ path[W] = V; /* 更新S到W的路径 */ } } } /* while结束*/ return true; /* 算法执行完毕,返回正确标记 */}
2多源最短路径问题
Floyd算法:
bool Floyd( MGraph Graph, WeightType D[][MaxVertexNum], Vertex path[][MaxVertexNum] ){ Vertex i, j, k; /* 初始化 */ for ( i=0; i<Graph->Nv; i++ ) for( j=0; j<Graph->Nv; j++ ) { D[i][j] = Graph->G[i][j]; path[i][j] = -1; } for( k=0; k<Graph->Nv; k++ ) for( i=0; i<Graph->Nv; i++ ) for( j=0; j<Graph->Nv; j++ ) if( D[i][k] + D[k][j] < D[i][j] ) { D[i][j] = D[i][k] + D[k][j]; if ( i==j && D[i][j]<0 ) /* 若发现负值圈 */ return false; /* 不能正确解决,返回错误标记 */ path[i][j] = k; } return true; /* 算法执行完毕,返回正确标记 */}
阅读全文
0 0
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- 最短路径问题
- POJ 1077 八数码(康托展开+暴力bfs)
- 图的拓扑排序及其应用
- Ubuntu终端常用的快捷键 Ubuntu中的许多操作在终端(Terminal)中十分的快捷,记住一些快捷键的操作更得心应手。在Ubuntu中打开终端的快捷键是Ctrl+Alt+T。其他的一些常用
- leetcode解题方案--063--Unique Paths II
- spring 哪里可以下载地址
- 最短路径问题
- HttpServer软件
- HDU2052Picture
- leetcode解题方案--064--Minimum Path Sum
- wget命令
- mac下使用brew安装mysql
- Excel在统计分析中的应用—第八章—假设检验-两总体方差的假设检验2(FTEST及F-检验宏)
- PJ的情书:纯模拟,桶排去重加上pair,用vector进行cmp重载
- Swagger2与Spring mvc集成