Floyd算法模板(多源最短)

 1 /*
 2 INPUT
 3 
 4 
 5 7 12
 6 1 2 24
 7 1 3 8
 8 1 4 15
 9 2 5 6
10 3 5 7
11 3 6 3
12 4 7 4
13 5 7 9
14 6 5 2
15 6 7 3
16 6 4 5
17 7 2 3
18 
19 5
20 1 2
21 3 6
22 1 7
23 4 4
24 3 7
25 
26 
27 OUTPUT
28 
29 1 to 2 need 17
30 3 to 6 need 3
31 1 to 7 need 14
32 4 to 4 need 0
33 3 to 7 need 6
34 
35 */
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <algorithm>
40 using namespace std;
41 const int inf=0x3f3f3f3f;
42 int n,m,w[110][110];
43 int main()
44 {
45     while(~scanf("%d%d",&n,&m))
46     {
47         memset(w,inf,sizeof(w));//先全部设为无穷大
48         for(int i=1; i<=n; i++)
49             w[i][i]=0;//自己到自己距离为0;
50         while(m--)
51         {
52             int u,v,c;
53             scanf("%d%d%d",&u,&v,&c);
54             if(c<w[u][v]);
55             w[u][v]=w[v][u]=c;
56         }
57         for(int k=1; k<=n; k++)//为了将i,j与k的情况讨论完,k作为中间点,要放在最外层
58         {
59             for(int i=1; i<=n; i++)
60             {
61                 for(int j=i+1; j<=n; j++)//因为是无向图,j>i或j<i(2,3),(3,2)的情况是一样的,不用重复计算
62                 {
63                     if(k!=i&&j!=k&&w[i][k]!=inf&&w[k][j]!=inf)//k作为中间点,三点不能重合,并且要满足k与i,j都有连接
64                     {
65                         w[i][j]=w[j][i]=min(w[i][j],w[i][k]+w[k][j]);//假如第三点之和小于起点直接到终点之和就更新
66                     }
67                 }
68             }
69         }
70         scanf("%d",&m);
71         while(m--)
72         {
73             int u,v;
74             scanf("%d %d",&u,&v);
75             printf("%d to %d need %d\n",u,v,w[u][v]);
76         }
77     }
78     return 0;
79 }

从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。

posted on 2015-09-01 15:09  甜蜜蜜吖甜蜜蜜  阅读(125)  评论(0编辑  收藏  举报

导航