1.问题
用Floyd算法求解下图各个顶点的最短距离。写出Floyd算法的伪代码和给出距离矩阵(顶点之间的最短距离矩阵)
2.解析
上图中有4个城市8条公路,公路上的数字表示这条公路的长短。请注意这些公路是单向的。我们现在需要求任意两个城市之间的最短路程,也就是求任意两个点之间的最短路径。这个问题这也被称为“多源最短路径”问题。
现在需要一个数据结构来存储图的信息,我们仍然可以用一个4*4的矩阵(二维数组e)来存储。比如1号城市到2号城市的路程为2,则设e[1][2]的值为2。2号城市无法到达4号城市,则设置e[2][4]的值为∞。另外此处约定一个城市自己是到自己的也是0,例如e[1][1]为0。
我们来想一想,根据我们以往的经验,如果要让任意两点(例如从顶点a点到顶点b)之间的路程变短,只能引入第三个点(顶点k),并通过这个顶点k中转即a->k->b,才可能缩短原来从顶点a点到顶点b的路程。那么这个中转的顶点k是1~n中的哪个点呢?甚至有时候不只通过一个点,而是经过两个点或者更多点中转会更短,即a->k1->k2b->或者a->k1->k2…->k->i…->b。比如上图中从4号城市到3号城市(4->3)的路程e[4][3]原本是12。如果只通过1号城市中转(4->1->3),路程将缩短为11(e[4][1]+e[1][3]=5+6=11)。其实1号城市到3号城市也可以通过2号城市中转,使得1号到3号城市的路程缩短为5(e[1][2]+e[2][3]=2+3=5)。所以如果同时经过1号和2号两个城市中转的话,从4号城市到3号城市的路程会进一步缩短为10。通过这个的例子,我们发现每个顶点都有可能使得另外两个顶点之间的路程变短。
3. 设计
1. #include
2. int main()
3. {
4. int e[10][10],k,i,j,n,m,t1,t2,t3;
5. int inf=99999999; //用inf(infinity的缩写)存储一个我们认为的正无穷值
6.
7. //读入n和m,n表示顶点个数,m表示边的条数
8. scanf("%d %d",&n,&m);
9.
10. //初始化
11. for(i=1;i<=n;i++)
12. for(j=1;j<=n;j++)
13. if(i==j)
14. e[i][j]=0;
15. else
16. e[i][j]=inf;
17.
18. //读入边
19. for(i=1;i<=m;i++)
20. {
21. scanf("%d %d %d",&t1,&t2,&t3);
22. e[t1][t2]=t3;
23. }
24.
25. //Floyd-Warshall算法核心语句
26. for(k=1;k<=n;k++)
27. for(i=1;i<=n;i++)
28. for(j=1;j<=n;j++)
29. if(e[i][j]>e[i][k]+e[k][j] )
30. e[i][j]=e[i][k]+e[k][j];
31.
32. //输出最终的结果
33. for(i=1;i<=n;i++)
34. {
35. for(j=1;j<=n;j++)
36. {
37. printf("%10d",e[i][j]);
38. }
39. printf("\n");
40. }
41.
42. return 0;
43. }
4. 源代码地址
https://github.com/Lin02993/-