给定高铁的规划方案,如何求任意两点的最短路呢?
方法是Floyd算法。
输入:创建图。
输出:任意两个顶点的最短路径以及长度。
运行结果:
算法思想:
1、计算从i出发,跳点为空,直接到j 的最短路。记做D[i][j]。
2、可选跳点为1时,i到j的路径分为两种情况:
或者不经过1, 此时前者最短为D[i][j],
或者经过1,此时最短为D[i][1]+D[1][j]
所以D[i][j]=min{D[i][j,D[i][1] + D[1][j] }
3、可选跳点为{1,2}时i到j的路径分为两种情况。
或者不经过2,此时最短为D[i][j],
或者经过2,此时最短为D[i][2] + D[i][j]
所以所以D[i][j]=min{D[i][j,D[i][2] + D[2][j] }
递推到可选跳点为{1..k}
D[i][j]=min{D[i][k],D[i][k] + D[k][j] }
可选跳点为{1..n}时,意味者对中间经过的顶点不加任何限制,此时所得的最短路就是全局最短路。D[i][j]=min{D[i][j],D[i][n] + D[n][j] }
算法复杂度O(G.vernum^3)
算法实现:
typedef char PathMatrix[50];
typedef int DistancMatrix[MVNUM][MVNUM];
void ShortestPath_FLOYD(MGraph G,PathMatrix P[MVNUM][MVNUM],DistancMatrix &D){
/*用Floyd算法求有向网G中各顶点v和w之间的最短路径P[v][w]及其带权长度D[v][w]。
计算得到跳点为空时的最短路D[i][j] 可选跳点为k时 或者不经过k 此时前者最短D
[i][j] 经过1此时最短为D[i][1]+D[1][k] 可选跳点到n时 意味着对中间的顶点没
有限制 ,此时的最短路就是全局最短路 */
int i,j,k;
char s[5],s1[50],s2[50];
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++) {
D[i][j]=G.arcs[i][j].adj;
if(D[i][j]<INFINITY){
s[0]=G.vexs[i];
s[1]='-';
s[2]='>';
s[3]=G.vexs[j];
s[4]='\0';
strcpy(P[i][j],s);
}
}
for(k=0;k<G.vexnum;k++)
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
if(D[i][j]>D[i][k]+D[k][j]) { //如果只关心两点间是否有通路,则可以用1和0表示连通与不连通
D[i][j]=D[i][k]+D[k][j]; //改为:d[i][j] = d[i][j]||(d[i][k] && d[k][j]) 是为有向图的传递闭包
strcpy(s1,P[i][k]);
strcpy(s2,P[k][j]);
strcpy(P[i][j],strcat(s1,Change(s2)));
}
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
if(i!=j)
printf("%s %d\n",P[i][j],D[i][j]);
}
修改字符串 删去s串第一个字母.
char *Change(char *s){
//修改字符串 删去s串第一个字母
int l=strlen(s);
for(int i=0;i<l;i++)
s[i]=s[i+1];
return s;
}
邻接表存储:
void ShortestPath_FLOYD(ALGraph G,PathMatrix P[MVNUM][MVNUM],DistancMatrix &D){
/*用Floyd算法求有向网G中各顶点v和w之间的最短路径P[v][w]及其带权长度D[v][w]。
计算得到跳点为空时的最短路D[i][j] 可选跳点为k时 或者不经过k 此时前者最短D
[i][j] 经过1此时最短为D[i][k]+D[1][k] 可选跳点到n时 意味着对中间的顶点没
有限制 ,此时的最短路就是全局最短路 */
int i,j,k;
char s[5],s1[50],s2[50];
ArcNode *p;
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
D[i][j]=INFINITY;
for(i=0;i<G.vexnum;i++)
for(p=G.vertices[i].firstarc;p!=NULL;p=p->nextarc) {
k=p->adjvex;
D[i][k]=p->adj;
s[0]=G.vertices[i].data;
s[1]='-';
s[2]='>';
s[3]=G.vertices[k].data;
s[4]='\0';
strcpy(P[i][k],s);
}
for(k=0;k<G.vexnum;k++)
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++){
if(D[i][j]>D[i][k]+D[k][j]){
D[i][j]=D[i][k]+D[k][j];
strcpy(s1,P[i][k]);
strcpy(s2,P[k][j]);
strcpy(P[i][j],strcat(s1,Change(s2)));
}
}
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
if(i!=j)
printf("%s %d\n",P[i][j],D[i][j]);
}