旅客从饭店前往公园,用整数
1
−
N
1-N
1−N给所有的巴士站编号,旅客巴士站编号为
1
1
1,公园巴士站的编号为
N
N
N。寻找一个最优乘车方案,使他在从饭店乘车到公园的过程中换车的次数最少。
输入第一行有两个数字
M
M
M和
N
N
N,表示开通了
M
M
M条单程巴士线路,总共有
N
N
N车站。从第二行到第
M
M
M行依次给出了第
1
1
1条到第
M
M
M条巴士线路的信息。其中第
i
+
1
i+1
i+1行给出的是第
i
i
i条巴士线路的信息,从左至右按运行顺序依次给出了该线路上的所有站号相邻两个站号之间。
本题最重要的是如何将其转化为最短路的问题,如果我们按照公交线路建图,就是模拟无法解决。所以我们换个思路建图,从左向右将一条线路的站点,都与这条线路的站点相连。这样建图可以使同一条线路上的任意两点间的距离为1,最少换乘次数=最少乘车次数-1。而最少乘车次数就转化为在权值全为1的图的最短路。
最后再注意输入格式,用字符串来读入,还要把第一行行末空格给去掉。
#include<bits/stdc++.h>
using namespace std;
int dis[5001][5001],a[10001];
int n,m,num,x;
string s;
void floyd()
{
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
if(i==k||dis[i][k]==999999)continue;
for(int j=1;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
int main()
{
cin>>m>>n;getline(cin,s);
memset(dis,999999,sizeof(dis));
for(int i=1;i<=m;i++)
{
num=0;
getline(cin,s);
for(int j=0;j<s.length();j++)
{
x=0;
while(s[j]>='0'&&s[j]<='9')
{
x=x*10+s[j]-'0';
j++;
}
a[++num]=x;
}
for(int j=1;j<=num;j++)
{
dis[j][j]=0;
for(int k=j+1;k<=num;k++)
dis[a[j]][a[k]]=1;
}
}
floyd();
if(dis[1][n]>=999999)cout<<"NO"<<endl;
else cout<<dis[1][n]-1<<endl;
return 0;
}