最短路(弗洛伊德)
哈利·波特与魔法石 ( Herry )
大年初三的那个晚上,小可可去电影院看了《哈利·波特与魔法石》,回到家坐在椅子上不一会儿就睡着了,并且梦见自己成了哈利·波特驰骋在充满了正义与邪恶的宇宙中执著地为了正义而战。
那天哈利·波特去拯救Super Samuel星球上的生灵。该星球上有七种不同的地形,依次分别是石子路、森林、草地、山地、雪地、沼泽和沙漠,用数字1~7来表示。任意两个城市之间都存在至少一条通路,而且任意两个能够不经过别的城市而直接通达的城市i和j之间都只存在一种地形ti,j 。奇怪的是,在Super Samuel星球上哈利·波特穿越地形u所需时间与该地形的区域大小无关,却与地形u的区域中是否有魔法石有关。如果地形u的区域中没有魔法石,哈利·波特要花hu的时间才能穿越该地区,否则他只要花一半的时间就能穿越了。已知 h1=2、h2=6、h3=4、h4=8、h5=6、h6=10、h7=14。su=1表示地形u的区域中有魔法石;su=0表示地形u的区域中没有魔法石。
例如,如右图所示,有4对可以直接通达的城市(城市1与2、1与3、2与4以及3与4);s1=0、s2=1、s3=s4=s5=s6=s7=0,即只有森林中有魔法石,因此穿越森林所花费的时间是6/2=3,穿越石子路和草地的时间仍然分别是2和4,如果哈利·波特想从城市1到达城市4,则最快的路线是经过城市2,这条路线需要的时间是2+3=5。
哈利·波特总是忙于铲除邪恶、伸张正义,没有时间去寻找从起点城市i到终点城市j之间的最快路线。现在聘你作为哈利·波特的助手编写程序寻找最快路线为哈利·波特腾出更多的时间来将正义事业进行到底。
输入:数据存放在当前目录下的文本文件“herry.in”中。
第一行有七个数,分别是s1、s2、……、s7 ;
第二行有两个数,依次分别是起点城市i和终点城市j ;
第三行有一个正整数C (C≤10000),表示随后的C行中每行存放了一对能直接通达的城市的信息。能直接通达的城市的信息由三个数组成,依次分别是两个城市的编号和这两个城市之间的地形。城市的编号都是不超过100的正整数,但是各个城市的编号未必连续。
文件里同一行中相邻的两个数都是用一个空白字符隔开的。
输出:答案输出到当前目录下的文本文件“herry.out”中。
以一行的形式输出起点城市i和终点城市j之间的最快路线所需要的时间。
输入输出举例:
|
输入文件:herry.in |
输出文件:herry.out |
|
0 1 0 0 0 0 0 1 4 4 1 2 1 1 3 1 2 4 2 3 4 3 |
5
|
首先处理一下数据...
然后弗洛伊德;
【Floyd的说明来自 http://www.cnblogs.com/hxsyl/p/3270401.html】
Floyd算法
参考了南阳理工牛帅(目前在新浪)的博客。
Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点到B,所以,我们假设dist(AB)为节点A到节点B的最短路径的距离,对于每一个节点K,我们检查dist(AK) + dist(KB) < dist(AB)是否成立,如果成立,证明从A到K再到B的路径比A直接到B的路径短,我们便设置 dist(AB) = dist(AK) + dist(KB),这样一来,当我们遍历完所有节点K,dist(AB)中记录的便是A到B的最短路径的距离。
很简单吧,代码看起来可能像下面这样:
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
for (int k=0; k<n; ++k) {
if (dist[i][k] + dist[k][j] < dist[i][j] ) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
但是这里我们要注意循环的嵌套顺序,如果把检查所有节点K放在最内层,那么结果将是不正确的,为什么呢?因为这样便过早的把i到j的最短路径确定下来了,而当后面存在更短的路径时,已经不再会更新了。
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int h[7]={2,6,4,8,6,10,14},i,j,k,n,m,map[105][105],a,b,c,ma,x1,y1;
int main()
{
freopen("herry.in","r",stdin);
freopen("herry.out","w",stdout);
for(i=0;i<7;i++)
{
cin>>j;
if(j==1) h[i]/=2;
}//处理路径长度
cin>>x1>>y1;
cin>>n;
for(i=0;i<n;i++)
{
cin>>a>>b>>c;
map[a][b]=h[c-1];//记录相邻城市的距离
if(ma<max(a,b)) ma=max(a,b);//记录最大的城市
}
// cout<<ma<<endl;
for(i=1;i<=ma;i++)
for(j=1;j<=ma;j++)
if(i==j) map[i][j]==9999;
else if(map[i][j]==0) map[i][j]=99999; //如果i j之间不相邻,设为无穷大(或足够大的数)
for(i=1;i<=ma;i++)
for(j=1;j<=ma;j++)
for(k=1;k<=ma;k++)
{
map[j][k]=min(map[j][k],map[j][i]+map[k][i]);
map[k][j]=map[j][k];
}//伟大的Floyd的核心代码
/* for(i=0;i<=ma;i++)
{
for(j=0;j<=ma;j++) printf("%8d",map[i][j]);
cout<<endl;
}*/
cout<<map[x1][y1]<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}

浙公网安备 33010602011771号