题意
给定若干站点,若干条单程路线,问从起点到终点最少要换乘几次。
思路
换乘多少次可以转换为乘坐过多少次车减1。在同一条路线中,任意一个在此路线上的车站均能沿着该路线的方向到达后面的车站。因此我们可以这样建图,建立一个有向图,如果一个点能仅通过一次车就到达另一个点,那么就连一条边,如果不能通过一次车到达,那么就不连边。这样问题就转化为了,起点到终点的最短路问题。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <sstream>
using namespace std;
const int N = 510;
int n,m;
int g[N][N];
int dist[N];
int stop[N];
int main()
{
cin >> m >> n;
memset(g,0x3f,sizeof(g));
for(int i=1;i<=n;i++) g[i][i] = 0;
string line;
getline(cin,line);
while(m--){
getline(cin,line);
stringstream ssin(line);
int p, cnt = 0;
while(ssin>>p) stop[cnt++] = p;
for(int i=0;i<cnt;i++){
for(int j=i+1;j<cnt;j++){
g[stop[i]][stop[j]] = 1;
}
}
}
memset(dist,0x3f,sizeof(dist));
queue<int> que;
dist[1] = 0;
que.push(1);
while(que.size()){
int t = que.front();
que.pop();
for(int i=1;i<=n;i++){
if(dist[i]>dist[t]+g[t][i]){
dist[i] = dist[t] + g[t][i];
que.push(i);
}
}
}
if(dist[n]==0x3f3f3f3f) cout << "NO" << endl;
else cout << max(dist[n]-1,0) << endl;
return 0;
}
收获
- 建图的时候,不一定建成真正的路线图,要根据实际问题进行抽象。
- 这道题的输入,一条路线经过若干站点,但是站点个数不给。所以可以考虑用特殊的输入方式。