您的位置:首页 > 其它

SHU1757 村村通工程(Floyd算法)

2015-12-27 14:33 246 查看

Description

某市启动村村通工程后,已修建了很多路,但尚未完成整个工程。不过路多了也烦恼,每次要从一个村镇到另一个村镇时,都有许多种道路方案可以选择,但走最短距离总是每个人追求的目标。

现在,已知一个村庄和另一个作为终点的村庄,请你计算出最短需要行走多少路程。

Input

本题目包含多组数据。每组数据第一行包含两个正整数N和M(0<N<200,0<M<1000),分别代表现有村镇的数目和已修建的道路的数目。村镇分别以0~N-1编号。

接下来是M行道路信息。每一行有三个整数A、B、X(0£A、B<N,A¹B,0<X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。

再接下一行有两个整数S、T(0£S,T<N),分别代表起点和终点。

Output

对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.

Sample Input

3 3

0 1 1

0 2 3

1 2 1

0 2

3 1

0 1 1

1 2

Sample Output

2

-1

Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B。所以,我们假设Dis(AB)为节点A到节点B的最短路径的距离,对于每一个节点X,我们检查Dis(AX) + Dis(XB) < Dis(AB)是否成立,如果成立,证明从A到X再到B的路径比A直接到B的路径短,我们便设置Dis(AB) = Dis(AX) + Dis(XB),这样一来,当我们遍历完所有节点X,Dis(AB)中记录的便是A到B的最短路径的距离。

根据这样的思路我写出了如下代码:

void floyd()
{
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
for(int k=0;k<n;k++)
map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
}


愉快地交了一发,发现WA了。

仔细思考可以想到,这样写其实是错误的。

举个栗子,我们要求A—>C的最短路

A—>B—>C 为5+6=11

A—>B—>D—>C 为5+2+3=10

明显下面那种更优,但是由于

for(int k=0;k<n;k++)
map[i][j]=min(map[i][j],map[i][k]+map[k][j])
是一个内循环,A—>C比A—>D先确定,也就无法得到下面那个正确的答案了。

那么如何解决呢?

for(int k=0;k<n;k++)
将其放在外循环。

这样一来,就是一开始只允许把0做为中转点,然后允许1,允许2……就能求到所有节点都能作为中转点的任意两点的最短路程了。

引用的别人的博客的图解,通俗易懂。/article/4122571.html

在只允许经过1和2号顶点的情况下,任意两点之间的最短路程更新为:



通过上图得知,在相比只允许通过1号顶点进行中转的情况下,这里允许通过1和2号顶点进行中转,使得e[1][3]和e[4][3]的路程变得更短了。

同理,继续在只允许经过1、2和3号顶点进行中转的情况下,求任意两点之间的最短路程。任意两点之间的最短路程更新为:



最后允许通过所有顶点作为中转,任意两点之间最终的最短路程为:



这道题的完整代码如下:

PS:如果要求路径的话可以加一条 path[i][j]=k;

#include<iostream>
#include<cstring>
#include<algorithm>
const int INF=0x3f3f3f3f;
using namespace std;
int map[1000][1000];
int n;
void floyd()
{
for(int k=0;k<n;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
}
int main(void)
{
int a,b,d,m,s,t;
while(cin>>n>>m)
{
memset(map,INF,sizeof(map));
for(int i=1;i<=m;i++)
{
cin>>a>>b>>d;
map[a][b]=map[b][a]=d;
}
cin>>s>>t;
floyd();
if(map[s][t]==INF)
cout<<"-1"<<endl;
else
cout<<map[s][t]<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: