大佬题解的c++版本
class Solution {
public:
vector<int> shortestAlternatingPaths(int n, vector<vector<int>> &redEdges, vector<vector<int>> &blueEdges) {
vector<set<int>> red_path(n, set<int>()); // red_path[i]: 以i为起点的红边的终点集合 set处理平行边
vector<set<int>> blue_path(n, set<int>()); // blue_path[i]: 以i为起点的蓝边的终点集合 set处理平行边
int step = 0; // 路径长度
vector<vector<int>> dist(2, vector<int>(n, -1)); // dist[0][i]: 以红边到达i点的最短路径长度 dist[1][i]: 以蓝边到达i点的最短路径长度
vector<int> ans(n, -1);
vector<int> cur_red(1, 0); // 下一步该走蓝边的节点
vector<int> cur_blue(1, 0); // 下一步该走红边的节点
for (auto edge : redEdges) {
red_path[edge[0]].insert(edge[1]);
}
for (auto edge : blueEdges) {
blue_path[edge[0]].insert(edge[1]);
}
dist[0][0] = 0;
dist[1][0] = 0;
while (!cur_red.empty() || !cur_blue.empty()) {
vector<int> new_red;
vector<int> new_blue;
++step;
// 下一步该走蓝边的节点
if (!cur_red.empty()) {
for (auto i : cur_red) {
for (auto next : blue_path[i]) {
if (dist[1][next] == -1) { // 同时处理环
dist[1][next] = step;
new_blue.push_back(next); // 下下一步应该走红边(下下下一步蓝边)
}
}
}
}
// 下一步该走红边的节点
if (!cur_blue.empty()) {
for (auto i : cur_blue) {
for (auto next : red_path[i]) {
if (dist[0][next] == -1) {
dist[0][next] = step;
new_red.push_back(next);
}
}
}
}
cur_red = new_red;
cur_blue = new_blue;
}
ans[0] = 0;
for (int i = 0; i < n; i++) {
if (dist[0][i] == -1 && dist[1][i] != -1) {
ans[i] = dist[1][i];
} else if (dist[0][i] != -1 && dist[1][i] == -1) {
ans[i] = dist[0][i];
} else if (dist[0][i] != -1 && dist[1][i] != -1) {
ans[i] = min(dist[0][i], dist[1][i]);
}
}
return ans;
}
};