【09年特长生第三题】【Floyed】导游的魔棒

博客讲述了如何利用Floyd算法解决一个旅行问题,即导游的魔棒可以使两个景点间距离减半,求使用魔棒后从入口到出口的最短路径。通过输入输出样例和解题思路,介绍了程序实现的细节。
摘要由CSDN通过智能技术生成

导 游 的 魔 棒 导游的魔棒


题目

小C“五一”节参加了五星旅行社组织的一次外出旅游,这次旅游中,小C遇到一件非常有趣的事: 五星旅行社的导游小张有一根魔棒,这根魔棒在每一次的旅游中可以产生一次魔力(也只能产生一次魔力),这魔力可以使两个景点间的距离减成原来的一半。小C在“五一”节的这次旅游中,很有幸是小张导游作为他们的导游,小张当然也没有忘记带他的魔棒,因为他可以发挥魔棒的作用,使路程减少呢。这次旅游中,去了一个有N个景点的旅游区,这个旅游区只有一个入口,在景点编号为1的地方,一个出口,在景点编号为N的地方,景点编号为1,2,3,…,N。在入口处有一个N×N的数据阵,描述了景点间的距离,a[I,j]表示景点i到景点j的距离。因为小C的公司有急事要小C尽快回来,现在小C要用张导游的魔棒,使得从入口到出口的距离最短。现在我们也来编一个程序:求将哪一条边减半后使从顶点1到顶点N的最短路径长度最短,输出这个最短距离,如果找不到从1到N的路径,则输出 -1 。


输入

从文件中c.in读入数据,文件第一行是一个正整数N(3 ≤ N ≤ 50),表示共有N个点,接下来是一个N行N列的数据阵,a[I,j]的值表示顶点i到顶点j的长度。

输出

只有一个数就是将一条边长减半后的从1到N的最短路径长度,结果四舍五入到小数后两位,如果找不到从1到N的路径,则输出 -1 。


输入样例

3
0  5  20
5  0  8
20  8  0

输出样例

9.00

解题思路

这题我们用 F l o y e d Floyed Floyed来做
a [ i ] [ j ] [ 0 / 1 ] a[i][j][0 / 1] a[i][j][0/1]表示 i i i走到 j j j 没用或者用了 将边减半的最短距离
然后直接 F l o y e d Floyed Floyed即可.

程序如下

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int n;
double a,f[10001][1001][10];
int main()
{
	scanf("%d",&n);
	for(int i = 1;i <= n; ++i)
	{
		for(int j = 1;j <= n; ++j)
		{
			scanf("%lf",&a);
			if(a ==  0) 
				f[i][j][0] = f[i][j][1] = 2147483647;//设初始值
			else
			{
				f[i][j][0] = a;
				f[i][j][1] = a / 2;//把每一条边都先算出减半后的路径
			} 
		} 
	}
	for(int k = 1; k <= n; ++k)
	{
		for(int i = 1; i <= n; ++i)
		{
			for(int j = 1; j <= n; ++j)
			{
				f[i][j][0] = min(f[i][j][0], f[i][k][0] + f[k][j][0]);
				f[i][j][1] = min(f[i][j][1], f[i][k][1] + f[k][j][0]);
				f[i][j][1] = min(f[i][j][1], f[i][k][0] + f[k][j][1]);
			}
		}
	}
	if (f[1][n][1] != 2147483647)
		printf("%0.2lf",f[1][n][1]); 
	else printf("-1");
	return 0;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值