描述
在小米之城,有 nnn 个小镇(从 1 开始编号),这些小镇通过 mmm 条双向火车铁轨相连,当然某些小镇之间也有公路相连。为了保证每两个小镇之间的人可以方便地互访,市长米小兔就在那些没有铁轨连接的小镇间建造了公路。在两个直接通过公路或铁路相连的小镇之间移动,需要花费 1 小时。火车只能走铁路,汽车只能走公路。现在有一辆火车和一辆汽车同时从小镇 1 出发,各自前往小镇 nnn。但是,他们中途不能同时停在同一个小镇(但是可以同时停在小镇 nnn)。现在请你来为火车和汽车分别设计一条线路,使火车和汽车尽可能快地到达小镇 nnn(即要求他们中最后到达小镇 nnn 的时间最短)。所有的公路或铁路可以被多次使用,求当火车、汽车中各自到达小镇时间最短时,总用时最小的一个。(火车和汽车可以同时到达小镇 nnn,也可以先后到达。)输入单组测试数据。首先有 2 个整数 nnn 和 mmm (2≤n≤400,0≤m≤n⋅n−122 \le n \le 400, 0 \le m \le n \cdot \frac{n-1}{2}2≤n≤400,0≤m≤n⋅2n−1) ,分别表示小镇的数目和铁轨的数目;接下来的 mmm 对数字,每对由两个整数 uuu 和 vvv 构成,表示小镇 uuu 和小镇 vvv 之间有一条铁路。(1≤u,v≤n,u≠v1 \le u,v \le n, u \neq v1≤u,v≤n,u̸=v)。输入中保证两个小镇之间最多有一条铁路直接相连。输出输出一个整数,表示答案,如果没有合法的路线规划,输出 -1.
输入样例:
4 2 1 3 3 4
输出样例:
2
题目网址:https://code.mi.com/problem/list/view?id=127
思路:对于汽车和火车,分别使用广度优先找到最短路,然后输出结果较大的。
我们可以用二维数组来记录哪些小镇用铁路相连,哪些用公路相连。如,2 1小镇用铁路相连,可以使map[2][1]=map[1][2]=1;1 4小镇用公路相连,则用map[1][4]=map[4][1]=2来记录。
代码如下:
#include<iostream>
#include<queue>
using namespace std;
int map[400][400] = { 0 };
int step[3][400] = { 0 }; //记录步数(需要通过几个镇子)
int bfs(int va, int n) { //参数va用来区分两次搜索
queue<int> que;
que.push(1);
while (!que.empty()) {
int k = que.front();
que.pop();
for (int i = 1 ; i <= n; i++) {
if (map[k][i] == va&&step[va][i]==0) {
que.push(i);
step[va][i] = step[va][k] + 1;
if(i==n){
return step[va][n];
}
}
}
}
return -1;
}
int main() {
int n, m, u, v;
cin >> n >> m;
for (int i = 0; i < m; i++) {
cin >> u >> v;
map[u][v] = map[v][u] = 1; //标记铁路
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == j) {
continue;
}
if (map[i][j] == 0) { //标记公路
map[i][j] = 2;
}
}
}
int a = bfs(1, n);
int b = bfs(2, n);
if (a == -1 || b == -1)
cout << -1;
else
cout << (a > b ? a : b);
return 0;
}