最优乘车(travel)
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 583 通过数: 81
【题目描述】
H城是一个旅游胜地,每年都有成千上万的人前来观光。为方便游客,巴士公司在各个旅游景点及宾馆,饭店等地都设置了巴士站并开通了一些单程巴士线路。每条单程巴士线路从某个巴士站出发,依次途经若干个巴士站,最终到达终点巴士站。
一名旅客最近到H城旅游,他很想去S公园游玩,但如果从他所在的饭店没有一路巴士可以直接到达S公园,则他可能要先乘某一路巴士坐几站,再下来换乘同一站台的另一路巴士, 这样换乘几次后到达S公园。
现在用整数1,2,…N 给H城的所有的巴士站编号,约定这名旅客所在饭店的巴士站编号为1,S公园巴士站的编号为N。
写一个程序,帮助这名旅客寻找一个最优乘车方案,使他在从饭店乘车到S公园的过程中换车的次数最少。
【输入】
第一行有两个数字M和N(1≤M≤100 1<N≤500),表示开通了M条单程巴士线路,总共有N个车站。从第二行到第M行依次给出了第1条到第M条巴士线路的信息。其中第i+1行给出的是第i条巴士线路的信息,从左至右按运行顺序依次给出了该线路上的所有站号相邻两个站号之间用一个空格隔开。
【输出】
只有一行。如果无法乘巴士从饭店到达S公园,则输出"N0",否则输出你的程序所找到的最少换车次数,换车次数为0表示不需换车即可到达。
【输入样例】
3 7 6 7 4 7 3 6 2 1 3 5
【输出样例】
2
【来源】
No
【算法分析】
本题难点就是建图,求换乘次数,和洛谷这题很想(点这里),我们可以想把一条路上的所有站之间距离都设为1.这样就可以累计乘车次数了,乘车次数=换乘次数+1
【代码实现】
下面按一本通打的代码超时,且给出超时地方#include<bits/stdc++.h>
using namespace std;
int main()
{int n,m;int g[501][501],a[10001];cin>>m>>n;memset(g,0x3f,sizeof(g));int i,j,k;for( i=1;i<=m;i++){int as=1,x=0;while(as!=10) //不知道为什么这里输出超时{x++;scanf("%d",&a[x]);as=getchar();}for( j=1;j<=x-1;j++) //建图:在一条公交线路中的任意两点之间建立边权为1(乘车一次)的边for( k=j+1;k<=x;k++)g[a[j]][a[k]]=1;}for(k=1;k<=n;k++)for(i=1;i<=n;i++)for(j=1;j<=n;j++){g[i][j]=min(g[i][j],g[i][k]+g[k][j]);}if(g[1][n]==0x3f3f3f3f) cout<<"NO"<<endl;else cout<<g[1][n]-1<<endl;//乘车次数=换乘次数+1return 0;
}
#include<bits/stdc++.h>
using namespace std;int g[501][501],a[521];
int main()
{int n,m;scanf("%d%d",&m,&n);memset(g,10000,sizeof(g));int i,j,k,as,x;for(int i=1;i<=n;i++)g[i][i]=1;char r;for( i=1;i<=m;i++){as=1,x=0;for(r =' '; r == ' '; scanf("%c", &r))scanf("%d", &a[++x]);for( j=1;j<=x-1;j++) //建图:在一条公交线路中的任意两点之间建立边权为1(乘车一次)的边for( k=j+1;k<=x;k++)g[a[j]][a[k]]=1;}for(k=1;k<=n;k++)for(i=1;i<=n;i++)for(j=1;j<=n;j++){g[i][j]=min(g[i][j],g[i][k]+g[k][j]);}if(g[1][n]>=10000) printf("NO");else printf("%d\n",g[1][n]-1);//乘车次数=换乘次数+1return 0;
}