最短路(弗洛伊德)

哈利·波特与魔法石 ( Herry )

大年初三的那个晚上,小可可去电影院看了《哈利·波特与魔法石》,回到家坐在椅子上不一会儿就睡着了,并且梦见自己成了哈利·波特驰骋在充满了正义与邪恶的宇宙中执著地为了正义而战。

那天哈利·波特去拯救Super Samuel星球上的生灵。该星球上有七种不同的地形,依次分别是石子路、森林、草地、山地、雪地、沼泽和沙漠,用数字1~7来表示。任意两个城市之间都存在至少一条通路,而且任意两个能够不经过别的城市而直接通达的城市ij之间都只存在一种地形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、s3s4s5s6s7=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;
}

 

posted @ 2016-06-21 21:23  wengsy150943  阅读(624)  评论(0)    收藏  举报