题目:http://111.231.101.32/problem.php?id=1005(自建OJ,欢迎光临)
如何读入,请见https://blog.csdn.net/qq_36314344/article/details/88550644
用bfs解题,题解如下:
1、开5个数组维护:
1)用a[s]记录过这个站点s的线路条数;
2)用clr[s][j]=i表示结点s所属第j条线路的编号是i;
3)用no[i][s]=t表示结点在编号为i的线路中是第t个站点;
4)用node[i][t]=s表示编号为t的线路中第t个站点是结点s;
5)用b[i]记录编号为i的线路共有多少个站点。
2、从结点1作为起点第一个结点存入队列,开始广搜,并记结点1的步数为-1,
3、将与head结点在同一线路中的点收入队列,并记这些tail结点的步数为head结点的步数+1。
4、如果搜索到结点n,则返回结点n的步数,否则返回INF,表示没有找到。
AC代码:
501][501];
int node[501][501];
int no[501][501];
int b[501];
bool vis[501];
int que[501][2];
int bfs(int x){
int head=0,tail=1;
que[1][0]=x;que[1][1]=-1;
while(head<tail){
head++;
int s=que[head][0],step=que[head][1];
vis[s]=1;
if(s==n)return step;
for(int i=1;i<=a[s];i++){/*过结点s共有a[s]条线路*/
int j=clr[s][i];/*过结点s第i条线路编号为j*/
/*no[j][s],编号j线路中,结点s的站点序号,
b[j],编号j的线路站点数目*/
for(int k=no[j][s];k<=b[j];k++ ){
int nd=node[j][k];/*no[j][k],编号j线路中,第k个站点*/
if(!vis[nd]){
vis[nd]=1;
tail++;
que[tail][0]=nd;
que[tail][1]=step+1;
}
}
}
}
return 1e9;
}
int main(){
cin>>m>>n;
/*读入数据,并初始化*/
c=getchar();
while(c==13){/*回车键13*/
c=getchar();
}
for(int i=1;i<=m;i++){
int t=0,s=0;
char c;
while(1){
c=getchar();
while(c==' '){
c=getchar();
}
t++;
s=0;
while(c<='9' && c>='0'){
s=s*10+c-'0';
c=getchar();
}
if(s){
a[s]++;/*过结点s的有a[s]条线路,a[s]会更新*/
clr[s][ a[s] ]=i;/*这条线路染成i*/
no[i][s]=t;/*编号为i的这条线路中结点s在第t个站*/
node[i][t]=s;/*编号为i的这条线路的第t个结点是s*/
b[i]=t;/*编号为i的这条线路共有t个结点,注意,t会更新*/
};
while(c==13)/*回车键13*/
c=getchar();
/*换行键10,或者到了文件结束标志EOF*/
if(c==10||c==EOF)break;
}
}
int ans=bfs(1);
if(ans==1e9)cout<<"NO"<<endl;
else cout<<ans<<endl;
return 0;
}