Description Link to heading
1129.shortest-path-with-alternating-colors
Solution Link to heading
First, we need represent the graph as an edge matrix, and we use bfs to find the shortest path.
In this problem, since the edge color of the shortest path must change along the path, when we judge whether the current node is visited, we should distinguish the cases that the current node is visited by red edges and the cases that the current node is visited by blue edges.
The element in the queue is tie(point, len, c_flag)
, which means the index of the current node, the length of the path to the current node(may not be the shortest), the color of the edge by which we visited the node(0 means blue and 1 means red).
The result of
q.push(0, 0, 0);
q.push(0, 0, 1);
bfs(q, red_connect, blue_connect, answer, n);
is the same as
q.push(0, 0, 0);
bfs(q, red_connect, blue_connect, answer, n);
q.pop();
q.push(0, 0, 1);
bfs(q, red_connect, blue_connect, answer, n);
Code Link to heading
class Solution {
public:
void bfs(queue<tuple<int, int, int>> q, vector<vector<int>> &red_connect, vector<vector<int>> &blue_connect, vector<int> &answer, int n, int i) {
vector<vector<int>> visited(n, vector<int>(2, 0)); // visited[k][1] == 1 means edge to be red, visited[k][0] == 1 means to be blue, both means the node has been visited.
int tmp_point = 0;
while (!q.empty()) {
auto [point, len, c_flag] = q.front();
visited[point][c_flag] = 1;
q.pop();
if (answer[point] == -1)
answer[point] = len;
else
answer[point] = min(answer[point], len);
if (c_flag == 0) {
for (int k = 0; k < red_connect[point].size(); k++) {
tmp_point = red_connect[point][k];
if (visited[tmp_point][1] != 1)
q.push({tmp_point, len + 1, 1});
}
} else {
for (int k = 0; k < blue_connect[point].size(); k++) {
tmp_point = blue_connect[point][k];
if (visited[tmp_point][0] != 1)
q.push({tmp_point, len + 1, 0});
}
}
}
}
vector<int> shortestAlternatingPaths(int n, vector<vector<int>> &redEdges, vector<vector<int>> &blueEdges) {
vector<vector<int>> red_connect(n);
vector<vector<int>> blue_connect(n);
for (auto &vec : redEdges) {
red_connect[vec[0]].push_back(vec[1]);
}
for (auto &vec : blueEdges) {
blue_connect[vec[0]].push_back(vec[1]);
}
vector<int> answer(n, -1);
answer[0] = 0;
queue<tuple<int, int, int>> q;
q.push({0, 0, 0});
q.push({0, 0, 1});
bfs(q, red_connect, blue_connect, answer, n, 0);
return answer;
}
};