您的位置:首页 > Web前端

HihoCoder1643 : 最少换乘([Offer收割]编程练习赛37)(bfs)

2017-12-28 09:28 501 查看

描述

小Ho居住的城市有N条公交车线路,其中第i条线路上有Ki个车站。

某些线路之间会有公共的车站,小Ho可以在这些车站从一条线路换乘到另一条线路。

现在给定N条公交车线路以及两个车站S和E,你能帮助小Ho计算从S到E最少换乘几次公交车吗?

输入

第一行包含三个整数N,S和E。

以下N行每行描述一条线路。第一个整数Ki代表该条线路包含的车站数。之后Ki个整数代表车站的编号。

注意车站编号不一定连续。

对于50%的数据,1 ≤ N ≤ 1000, 1 ≤ Ki ≤ 100

对于100%的数据,1 ≤ N ≤ 50000, 1 ≤ Ki ≤ 80000,1 ≤ 所有Ki之和 ≤ 500000, 1 ≤ 车站编号 ≤ 5000000。

输出

输出最少换乘次数。如果S到E不可达,输出-1。

样例输入

3 123 345
4 321 375 123 456
4 222 333 123 444
2 222 345

样例输出

1

由于每一条线和每一班车都最多操作一次,所以复杂度是线性的。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<int>G[50010];//每个线路有哪些车次
vector<int>bus[5000010];//每趟车路过那些线。
int dis[5000010];//站
int vis[50010];//线
int q[5001001],head,tail;
int n,s,t;
void bfs()
{
q[++head]=s;dis[s]=1;
while(tail<head){
int u=q[++tail],v;
int L1=bus[u].size(),L2,i,j;
for(i=0;i<L1;i++){
v=bus[u][i];
if(vis[v]) continue;//一条线只访问依此
vis[v]=1; L2=G[v].size();
for(j=0;j<L2;j++){
if(!dis[G[v][j]]) {//一辆车只访问依此
if(G[v][j]==t) { dis[t]=dis[u];return ;}
dis[G[v][j]]=dis[u]+1;
// cout<<G[v][j]<<" "<<dis[G[v][j]]<<endl;
q[++head]=G[v][j];
}
}
}
}
}
int main()
{
scanf("%d%d%d",&n,&s,&t);
for(int i=1;i<=n;i++){
int num,x;scanf("%d",&num);
for(int j=1;j<=num;j++){
scanf("%d",&x);
G[i].push_back(x);
bus[x].push_back(i);
}
}   bfs();
if(!dis[t]) printf("-1\n");
else printf("%d\n",dis[t]-1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: