<—点个赞吧QwQ
宣传一下算法提高课整理{:target=”_blank”}
$H$ 城是一个旅游胜地,每年都有成千上万的人前来观光。
为方便游客,巴士公司在各个旅游景点及宾馆,饭店等地都设置了巴士站并开通了一些单程巴士线路。
每条单程巴士线路从某个巴士站出发,依次途经若干个巴士站,最终到达终点巴士站。
一名旅客最近到 $H$ 城旅游,他很想去 $S$ 公园游玩,但如果从他所在的饭店没有一路巴士可以直接到达 $S$ 公园,则他可能要先乘某一路巴士坐几站,再下来换乘同一站台的另一路巴士,这样换乘几次后到达 $S$ 公园。
现在用整数 $1,2,…N$ 给 $H$ 城的所有的巴士站编号,约定这名旅客所在饭店的巴士站编号为 $1$,$S$ 公园巴士站的编号为 $N$。
写一个程序,帮助这名旅客寻找一个最优乘车方案,使他在从饭店乘车到 $S$ 公园的过程中换乘的次数最少。
输入格式
第一行有两个数字 $M$ 和 $N$,表示开通了 $M$ 条单程巴士线路,总共有 $N$ 个车站。
从第二行到第 $M+1$ 行依次给出了第 $1$ 条到第 $M$ 条巴士线路的信息,其中第 $i+1$ 行给出的是第 $i$ 条巴士线路的信息,从左至右按运行顺序依次给出了该线路上的所有站号,相邻两个站号之间用一个空格隔开。
输出格式
共一行,如果无法乘巴士从饭店到达 $S$ 公园,则输出 NO
,否则输出最少换乘次数,换乘次数为 $0$ 表示不需换车即可到达。
数据范围
$1 \\le M \\le 100$,
$2 \\le N \\le 500$
输入样例:
3 7
6 7
4 7 3 6
2 1 3 5
输出样例:
2
思路
这道题就是把每一个巴士线路的所有前面的点到后面的点连一条边。
最后从$1$跑一遍$\text{BFS}$即可。
代码
#include <iostream>
#include <queue>
#include <cstring>
#include <sstream>
using namespace std;
const int N = 510,INF = 0x3f3f3f3f;
int m,n;
string line;
bool g[N][N];
int stop[N];
int dist[N];
int bfs () {
queue <int> q;
q.push (1);
memset (dist,0x3f,sizeof (dist));
dist[1] = 0;
while (!q.empty ()) {
int t = q.front ();
q.pop ();
for (int i = 1;i <= n;i++) {
if (g[t][i] && dist[i] > dist[t]+1) {
dist[i] = dist[t]+1;
q.push (i);
}
}
}
return dist[n];
}
int main () {
cin >> m >> n;
getline (cin,line);
while (m--) {
getline (cin,line);
stringstream ss (line);
int p,cnt = 0;
while (ss >> p) stop[++cnt] = p;
for (int i = 1;i <= cnt;i++) {
for (int j = i+1;j <= cnt;j++) {
g[stop[i]][stop[j]] = 1;
}
}
}
int ans = bfs ();
if (ans == INF) puts ("NO");
else cout << max (ans-1,0) << endl;
return 0;
}
为死猫刷赞()
.
hh 这个说是bfs 其实也好像spfa算法 (%%%)
应该是Dijkstra
拉莱耶!!!(牛逼)
为什么是
可以理解成走的距离越远,换乘次数越少吗
好像我理解了,这只是向外扩张所有情况,第一次搜到的就是最短的,和我刚刚想的思路没有关系。
为什么在while之前不加这个东西getline (cin,line)的结果是错的?
因为有换行
$cin$ 没有读走回车,所以需要加这一句读走回车。
对