原题链接
题目大意
给定 n n n条单向的公交线路,求从 1 1 1号站到 n n n号站的最少转车次数。
输入格式
第
1
1
1行有两个数字
m
m
m和
n
n
n,表示开通了
m
m
m条单程巴士线路,总共有
n
n
n个车站。
从第
2
2
2行到第
m
m
m行依次给出了第
1
1
1条到第
m
m
m条巴士线路的信息。其中第
i
+
1
i+1
i+1行给出的是第
i
i
i条巴士线路的信息,从左至右按运行顺序依次给出了该线路上的所有站号相邻两个站号之间用一个空格隔开。
输出格式
一个整数,表示最少步数,如果到达不了,输出NO
。
S a m p l e \mathbf{Sample} Sample I n p u t \mathbf{Input} Input
3 7
6 7
4 7 3 6
2 1 3 5
S a m p l e \mathbf{Sample} Sample O u t p u t \mathbf{Output} Output
2
H
i
n
t
&
E
x
p
l
a
i
n
\mathbf{Hint\&Explain}
Hint&Explain
公交线路如图所示。
先从
1
1
1号点坐车坐到
3
3
3号点,再坐到
6
6
6号点,再坐到
7
7
7号点,总共转车
2
2
2次。
数据范围
对于 100 % 100\% 100%的数据满足: 1 ≤ m ≤ 100 , 1 < n ≤ 500 1 \le m \le 100,1 < n \le 500 1≤m≤100,1<n≤500。
解题思路
本题可以用
b
f
s
bfs
bfs解决。
我们可以把上面的行车路线,转换成一个邻接矩阵的形式,再进行
b
f
s
bfs
bfs。
最后转换成的是这个样子:
1 2 3 4 5 6 7
---------------
1 | 0 0 1 0 1 0 0
2 | 1 0 1 0 1 0 0
3 | 0 0 0 0 1 1 0
4 | 0 0 1 0 0 1 1
5 | 0 0 0 0 0 0 0
6 | 0 0 0 0 0 0 1
7 | 0 0 1 0 0 1 0
其中纵坐标代表从哪里出发,横坐标代表到哪里,1
代表可以到达,0
代表到达不了。
那么,这题就转换成了一个利用邻接矩阵,求
1
1
1号站到
n
n
n号站的最短步数。
注意事项:
1.这一题的输入是没有给你要输入多少个数的,所以要逐个判断字符,直到读到
\n
为止,再开始读下一行。
2.公交车是单向的,不是双向的,而且方向是输入的顺序,即从左到右。(当时我就在这里调了半个小时)
3.建立邻接矩阵的时候,要把一条路线上这个点所有的可以到达的都标记为1
。
最后,祝大家早日
进阶练习
洛谷上的题目,和这题题面一样。
P5767 [NOI1997] 最优乘车
上代码
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
queue<int> q;
int vis[1010];
int a[1010][1010];
int n,m;
int main()
{
cin>>n>>m;
if(m==1)
{
cout<<0<<endl;
return 0;
}
getchar();
for(int i=1; i<=n; i++)
{
vector<int> elements;
char c;
int temp=0;
while((c=getchar())!='\n')
{
if(c==' ')
{
elements.push_back(temp);
temp=0;
}
else
temp=temp*10+(c-'0');
}
elements.push_back(temp);
temp=0;
for(int j=0; j<elements.size(); j++)
for(int k=j+1; k<elements.size(); k++)
a[elements[j]][elements[k]]=1;
}
memset(vis,-0x7f,sizeof(vis));
q.push(1);
vis[1]=-1;
while(q.size())
{
int now=q.front();
// cout<<"\t"<<now<<endl;
q.pop();
if(now==m)
{
cout<<vis[now]<<endl;
return 0;
}
for(int i=1; i<=m; i++)
if(i!=now&&a[now][i]&&vis[i]<0)
{
q.push(i);
vis[i]=vis[now]+1;
}
}
cout<<"NO"<<endl;
return 0;
}
完美切题 ∼ \sim ∼