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 30 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; }
相关文章推荐
- 修改Android签名证书keystore的密码、别名alias以及别名密码
- ubuntu以root身份登录图形界面的小技巧
- objective-c static变量的使用总结
- CSS 布局口诀
- Celery 提示[ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@127.0.0.1:5672//: [Errno 61] Connection refused.
- jeety and tomcat plugins In Maven
- Java中的委托模式
- 零基础入门学习Python(22):魔法方法(2)算术运算
- 网络协议之《网络七层协议》
- 网络流之最小割
- Linux基本知识
- Android 学习
- uva10954
- 推荐软件
- 《python科学计算》matplotlib学习
- Sublime Text3 写js智能提示插件Andyjs2下载及使用方法
- canvas基础学习(四)
- MVC,MVP 和 MVVM 的图示
- vcard通讯录格式及手机名片制作
- 立方尾不变