最短路径一般是基于网图来说的(带有权值的连通图),不带权值可以考虑权值为1来计算。

最短路径是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点是源点,最后一个顶点是终点。

求解最短路径的两种算法。迪杰斯特拉算法和弗洛伊德算法。

1、迪杰斯特拉(Dijkstra)算法

    用来求某个顶点到其余所有顶点的最短路径

算法介绍

求V0到其余各个顶点的最短路径。

(1)初始化,P={V0},D0(V0到V0的距离)= 0;Di表示V0到Vi顶点的距离,Di = di0,i不等于0,规定如果Vi顶点与V0不直接相连,则Di = 无穷大。

(2)寻找下一个目标顶点,即在Di(i不属于P)中选择一个点j,是Dj最小,则选择的点Vj放到P中,Vj所在的路径是最短路径。

(3)更新Di(i不属于P),Di = min[Di(旧的,更新之前的),Dj + dji ],更新完所有i(不属于P),返回第2步。直达所有顶点存储到P中。

#define MAXVEX 9
#define INFINITY 65535
typedef int Pathmatirx[MAXVEX];
typedef int ShortPathTable[MAXVEX];
void ShortestPaht_Dijkstra(MGraph G, int V0, Pathmatirx *P, ShortPathTable *D)
{
int v,w,k,min;
int final[MAXVEX];  /*final[w]=1表示求得顶点V0至Vw的最短路径*/
for(v=0;v 
  

 

2、弗洛伊德(Floyd)算法

    用来求解任意顶点到任意顶点的最短路径。

    是一种用于寻找给定的加权图中顶点间最短路径的算法

    核心思路:

    通过一个图的权值矩阵求出它的每两点之间的最短路径。

(1)从任意一条单边路径开始,所有两点之间的距离是边的权,如果两点之间没有变相连,则权为无穷大。

(2)对于每一点U和V,看看是否存在一个顶点W使得从U到W再到V比已知的路径更短,如果是更新它。

把图用邻接矩阵G表示出来,如果从Vi到Vj有路可达,则G[i,j]=d,d表示该路的长度;否则G[i,j]=无穷大。

定义一个矩阵D用来记录所插入的点的信息,D[i,j]表示从从Vi到Vj需要经过的点,初始化D[i,j]=j。

把各个顶点插入图中,比较插点后的距离和原来的距离G[i,j] = min ( G[i,j] ,G[i,k] + G[k,j]);

如果G[i,j]的值变小,则D[i,j]=k。

在G中包含两点之间最短路径的长度的信息,而在D中则包含了最短路径(具体路径)的信息。

#include 
#define MAXVEX 100
typedef int Pathmatirx[MAXVEX][MAXVEX];
typedef int ShorPathTable[MAXVEX][MAXVEX];
/*Floyd算法,求网图G中各顶点v到其余顶点w的最短路径P[v][w]及带权长度D[v][w]*/
void ShortestPath_Floyd(MGraph G, Pathmatirx *P, ShortPathTable *D)
{
int v,w,k;
for(v=0; v (*D)[v][k] + (D)[k][w])
{
(*D)[v][w] = (*D)[v][k] + (*D)[k][w];
(*P)[v][w] = (*P)[v][k];
}
}
}
}
}