版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38083668/article/details/82918928
最优乘车
时间限制: 1 Sec 内存限制: 128 MB
题目描述
H城是一个旅游胜地,为方便游客,在各个旅游景点及宾馆、饭店等地设置了N个巴士站,并开通了M条一些单向巴士线路。
现在用整数1,2,…,n给H城的所有巴士站编号,约定CUP饭店的巴士站编号为1,S公园巴士站的编号为N。
写一个程序,寻找一个从CUP饭店到S公园的过程中换车的次数最少的乘车方案。
输入
输入第一行有两个数字M和N(1<=M<=100 1<N<=500)
输出
输出只有一行。如果无法乘巴士从饭店到达S公园,则输出
“N0”,否则输出你的程序所找到的最少换车次数,换车次数为0表示不需换车即可到达·
样例输入
3 7
6 7
4 7 3 6
2 1 3 5
样例输出
2
解析:
挺有意思的一道题。
最初想成了分层图发现不对劲,然后就没有然后了。。。
看了下题解发现真是妙。
步骤:
1、把同一条线路上的站点相互之间的距离赋为 1;
2、不是同一线路上的站点相互之间的距离赋很大一个值;
3、Floyd 求任意两站点 之间的最短路 ;
4、最后即为所求。
如何理解?的意思相当于在换路线到对答案贡献为1,跑最短路后就是最小贡献就是答案。最后-1是因为到起点不需要换乘。
不过讲道理这道题怎么可能过得去,然而亲测的确能过而且还不慢。。。
还有人说输入有点恶心其实只需要用一个字符判断有没有读到行末或换行符就行了。
代码:
#include <bits/stdc++.h>
using namespace std;
const int Max=505;
int n,m,f[Max][Max],tot,num[Max],x;
int main()
{
scanf("%d%d",&m,&n);
memset(f,0x3f3f3f,sizeof(f));
for(int i=1;i<=m;i++)
{
tot=0;char ch='0';
do
{
if(ch=='\n')break;
scanf("%d",&x);
num[++tot]=x;
}while(scanf("%c",&ch)!=EOF);
for(int i=1;i<tot;i++)
for(int j=i+1;j<=tot;j++) f[num[i]][num[j]]=1;
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
if(f[1][n]<=m+1) cout<<f[1][n]-1;
else cout<<"NO";
return 0;
}