每一对顶点之间的最短路径
// func7-2.cpp 算法7.16,algo7-7.cpp和algo7-9.cpp用到 void ShortestPath_FLOYD(MGraph G,PathMatrix P,DistancMatrix D) { // 用Floyd算法求有向网G中各对顶点v和w之间的最短路径P[v][w]及其带权长度D[v][w]。 // 若P[v][w][u]为TRUE,则u是从v到w当前求得最短路径上的顶点。算法7.16 int u,v,w,i; for(v=0;v<G.vexnum;v++) // 各对结点之间初始已知路径及距离 for(w=0;w<G.vexnum;w++) { D[v][w]=G.arcs[v][w].adj; // 顶点v到顶点w的直接距离 for(u=0;u<G.vexnum;u++) P[v][w][u]=FALSE; // 路径矩阵初值 if(D[v][w]<INFINITY) // 从v到w有直接路径 P[v][w][v]=P[v][w][w]=TRUE; // 由v到w的路径经过v和w两点 } for(u=0;u<G.vexnum;u++) for(v=0;v<G.vexnum;v++) for(w=0;w<G.vexnum;w++) if(D[v][u]<INFINITY&&D[u][w]<INFINITY&&D[v][u]+D[u][w]<D[v][w]) { // 从v经u到w的一条路径更短 D[v][w]=D[v][u]+D[u][w]; // 更新最短距离 for(i=0;i<G.vexnum;i++) P[v][w][i]=P[v][u][i]||P[u][w][i]; // 从v到w的路径经过从v到u和从u到w的所有路径 } }
// algo7-7.cpp 实现算法7.16的程序 #define MAX_NAME 5 // 顶点字符串的最大长度+1 #define MAX_INFO 20 // 相关信息字符串的最大长度+1 typedef int VRType; typedef char VertexType[MAX_NAME]; typedef char InfoType; #include"c1.h" #include"c7-1.h" // 邻接矩阵存储结构 #include"bo7-1.cpp" // 邻接矩阵存储结构的基本操作 typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 3维数组 typedef int DistancMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 2维数组 #include"func7-2.cpp" // 求有向网中各对顶点之间最短距离的Floyd算法 void main() { MGraph g; int i,j,k,l,m,n; PathMatrix p; // 3维数组 DistancMatrix d; // 2维数组 CreateDN(g); // 构造有向网g for(i=0;i<g.vexnum;i++) g.arcs[i][i].adj=0; // ShortestPath_FLOYD()要求对角元素值为0,因为两点相同,其距离为0 Display(g); // 输出有向网g ShortestPath_FLOYD(g,p,d); // 求每对顶点间的最短路径,在func7-2.cpp中 printf("d矩阵:\n"); for(i=0;i<g.vexnum;i++) { for(j=0;j<g.vexnum;j++) printf("%6d",d[i][j]); printf("\n"); } for(i=0;i<g.vexnum;i++) for(j=0;j<g.vexnum;j++) if(i!=j) printf("%s到%s的最短距离为%d\n",g.vexs[i],g.vexs[j],d[i][j]); printf("p矩阵:\n"); for(i=0;i<g.vexnum;i++) for(j=0;j<g.vexnum;j++) if(i!=j) { printf("由%s到%s经过:",g.vexs[i],g.vexs[j]); for(k=0;k<g.vexnum;k++) if(p[i][j][k]==1) printf("%s ",g.vexs[k]); printf("\n"); } }
代码的运行结果:
请输入有向网G的顶点数,弧数,弧是否含其它信息(是:1,否:0): 3,5,0(见图770)
请输入3个顶点的值(<5个字符):
A B C
请输入5条弧的弧尾弧头权值(以空格作为间隔):
A B 4
A C 11
B A 6
B C 2
C A 3
3个顶点5条边或弧的有向网。顶点依次是: A B C
G.arcs.adj:
0 4 11
6 0 2
3 32767 0
G.arcs.info:
顶点1(弧尾) 顶点2(弧头) 该边或弧的信息:
d矩阵:
0 4 6
5 0 2
3 7 0
A到B的最短距离为4
A到C的最短距离为6
B到A的最短距离为5
B到C的最短距离为2
C到A的最短距离为3
C到B的最短距离为7
p矩阵:
由A到B经过:A B
由A到C经过:A B C
由B到A经过:A B C
由B到C经过:B C
由C到A经过:A C
由C到B经过:A B C
求有向网中各对顶点之间最短距离的Floyd 算法ShortestPath_FLOYD()要求其网的邻
接矩阵中对角元素的权值为0。因为用邻接矩阵表示各顶点之间的距离,显然,同一点之
间的距离为0。
ShortestPath_FLOYD()算法的思路很简单,首先以2 顶点之间的直接路径为最短路
径,如果能找到第3 点,使2 顶点通过第3 点的路径比直接路径要短,则以这3 点形成的
路径为2 顶点之间的最短路径。依次再找第4 点、第5 点、⋯⋯ 如以上程序运行结果所
示,根据图770 及邻接矩阵,A→C 的直接距离是11,但A→B→C 的距离是6,则以6
取代11 作为A→C 的最短距离。
ShortestPath_FLOYD()不仅可用于有向网,也可用于无向网。因为无向网的1 条边相
当于有向网的2 条弧。
教科书中图7.33 是描述中国大陆地区铁路交通的无向网。程序algo7-9.cpp 利用
ShortestPath_FLOYD()可求得该网中每2 个站点之间的最短距离。该无向网的数据是利用
文件map.txt 输入的。map.txt 的内容如下(在教科书中图7.33 的基础上另加孤立顶点
台北):
26
30
乌鲁木齐
呼和浩特
哈尔滨
西宁
兰州
成都
昆明
贵阳
南宁
柳州
株州
广州
深圳
南昌
福州
上海
武汉
西安
郑州
徐州
北京
天津
沈阳
大连
长春
台北
乌鲁木齐兰州1892
呼和浩特兰州1145
呼和浩特北京668
哈尔滨长春242
西宁兰州216
兰州西安676
西安成都842
西安郑州511
成都昆明1100
成都贵阳967
昆明贵阳639
贵阳柳州607
柳州株州672
柳州南宁255
贵阳株州902
株州武汉409
株州广州675
株州南昌367
广州深圳140
南昌福州622
南昌上海825
武汉郑州534
郑州北京695
郑州徐州349
徐州天津674
徐州上海651
北京天津137
天津沈阳704
沈阳大连397
沈阳长春305
每当夜深人静的时候,想想今天发生了什么,失去了什么,得到了什么,做了什么,没做什么,该做什么,不该做什么,明天要做什么!