题目链接:https://leetcode.cn/problems/bus-routes/description/
题目大意:给出一系列公交车路线routes[][]
,每条路线上有一系列车站,可以搭乘同一班公交车经过这些车站。给出起点车站和终点车站,求最小的需要搭乘的公交车数量。
思路:其实就是把每条路线看成一个super-vertex求最短路径(这里就是建图的时候麻烦点,要用到一个map
)。因为求最短,那么BFS更合适(我一开始还写DFS,后来发现同时【保留最短路径】【返回是否找得到终点】太麻烦了)。然而做了还是超时了,因为我保存这些super-vertex的连接边方式是用邻接表...看了题解直接用n*n
矩阵保存边即可。
BFS时如何保存【搭乘的车的数量】呢?这就用到上次做层序遍历学到的BFS方法了,详见:https://blog.csdn.net/Rstln/article/details/139954638
注意点是如果起点和终点一样,是不需要乘车的,返回0
即可。
完整代码:
cpp
class Solution {
public:
int numBusesToDestination(vector<vector<int>>& routes, int source, int target) {
if (source == target)
return 0;
int n = routes.size();
vector<vector<bool>> g(n, vector<bool>(n, false));
unordered_map<int, unordered_set<int>> blg;
for (int i = 0; i < n; i++) {
for (auto st: routes[i]){
for (auto it = blg[st].begin(); it != blg[st].end(); it++) {
g[i][*it] = g[*it][i] = true;
}
blg[st].insert(i);
}
}
set<int> des;
for (auto it = blg[target].begin(); it != blg[target].end(); it++)
des.insert(*it);
if (des.empty())
return -1;
int res = -1;
for (auto st = blg[source].begin(); st != blg[source].end(); st++) {
queue<int> q;
vector<bool> known(n, false);
q.push(*st);
known[*st] = true;
int tmp = 0;
bool flag = false;
while (!q.empty()) {
tmp++;
for (int i = q.size(); i > 0; i--) {
int node = q.front();
q.pop();
if (des.count(node)) {
flag = true;
break;
}
for (int nb = 0; nb < n; nb++) {
if (!known[nb] && g[node][nb]) {
q.push(nb);
known[nb] = true;
}
}
}
if (flag)
break;
}
if (flag) {
if (res == -1)
res = tmp;
else
res = min(res, tmp);
}
}
return res;
}
};