最优乘车

题目描述
HH 城是一个旅游胜地,每年都有成千上万的人前来观光。为方便游客,巴士公司在各个旅游景点及宾馆,饭店等地都设置了巴士站并开通了一些单程巴上线路。每条单程巴士线路从某个巴士站出发,依次途经若干个巴士站,最终到达终点巴士站。
一名旅客最近到 HH 城旅游,他很想去 SS 公园游玩,但如果从他所在的饭店没有一路巴士可以直接到达 SS 公园,则他可能要先乘某一路巴士坐几站,再下来换乘同一站台的另一路巴士, 这样换乘几次后到达 SS 公园。
现在用整数 1 , 2 , … , N1,2,…,N 给 HH 城的所有的巴士站编号,约定这名旅客所在饭店的巴士站编号为 1 … S1…S 公园巴士站的编号为 NN 。
写一个程序,帮助这名旅客寻找一个最优乘车方案,使他在从饭店乘车到 SS 公园的过程中换车的次数最少。

输入格式
第一行有两个数字 MM 和 NN ( 1 \le M \le 100 1≤M≤100 , 1 < N \le 500 1<N≤500),表 示开通了 MM 条单程巴士线路,总共有 NN 个车站。
从第二行到第 MM 行依次给出了第 11 条到第 MM 条巴士线路的信息。其中第 i+1i+1 行给出的是第 ii 条巴士线路的信息,从左至右按运行顺序依次给出了该线路上的所有站号相邻两个站号之间用一个空格隔开。

输出格式
只有一行。如果无法乘巴士从饭店到达 SS 公园,则输出 N0,否则输出你的程序所找到的最少换车次数,换车次数为 00 表示不需换车即可到达•。

输入输出样例
输入 #1
3 7
6 7
4 7 3 6
2 1 3 5
输出 #1
2

分析
由题意得,我们可以采用广搜
但是它们的代价不一样

所以我们还有将它们连接起来,预处理

for(int j=1;j<=a[0]-1;j++)
	  for(int k=j+1;k<=a[0];k++)
	   b[a[j]][a[k]]=1;

输入可以采用上次教的快读

for(int i=0;i<=m;i++)
	{
   
	 memset(a,0,sizeof(a)); a[0]=1;
	 do
	 {
   
	  x=getchar();
	  if(x>='0'&&x<='9')a[a[0]]=a[a[0]]*10+x-48;else a[0]++;
	 }while (x!='\n'&&x!=EOF); a[0]--;

还有,bfs又怎么去实现呢?
我们用一个变量去记录父节点,一个去记录已经换乘次数,一个去判断是否重复
就行了

AC代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,fa[10005],st[10005],f[10005],head,tail,b[1005][1005],a[1005];
char x;
void bfs() 
{
   
	tail=1;
	fa[1]=1;//父节点为1
	st[1]=-1;//初始值**一定要为-1**
	f[1]=1;//车1已经坐过
	do
	{
   
		head++;
		for(int i=1;i<=n;i++)
		 if(b[fa[head]][i]==1&&f[i]==0)//判断
		 {
   
			tail++;
			fa[tail]=i;
			st[i]=st[fa[head]]+1;
			f[i]=1;
		 }
	}while(head<tail&&f[n]==0);
	if(head==tail)cout<<"NO";else cout<<st[n];//有到不了的情况
}
int main()
{
   	
    cin>>m>>n;
	for(int i=0;i<=m;i++)//快读
	{
   
	 memset(a,0,sizeof(a)); a[0]=1;
	 do
	 {
   
	  x=getchar();
	  if(x>='0'&&x<='9')a[a[0]]=a[a[0]]*10+x-48;else a[0]++;
	 }while (x!='\n'&&x!=EOF); a[0]--;
	 for(int j=1;j<=a[0]-1;j++)//预处理
	  for(int k=j+1;k<=a[0];k++)
	   b[a[j]][a[k]]=1;
	}
	bfs();
}

谢谢观看