1129. Shortest Path with Alternating Colors

问题:

给定n个节点,和节点之间的连线关系,构成有向图。

  • 红线 red_edges:[a,b]: a->b
  • 蓝线 blue_edges:[a,b]: a->b

求从节点0,到各个节点(红蓝线交替)的最短距离。

若对于某个节点不存在这样的通路,那么该节点的结果为-1。

Example 1:
Input: n = 3, red_edges = [[0,1],[1,2]], blue_edges = []
Output: [0,1,-1]

Example 2:
Input: n = 3, red_edges = [[0,1]], blue_edges = [[2,1]]
Output: [0,1,-1]

Example 3:
Input: n = 3, red_edges = [[1,0]], blue_edges = [[2,1]]
Output: [0,-1,-1]

Example 4:
Input: n = 3, red_edges = [[0,1]], blue_edges = [[1,2]]
Output: [0,1,2]

Example 5:
Input: n = 3, red_edges = [[0,1],[0,2]], blue_edges = [[1,0]]
Output: [0,1,1] 

Constraints:
1 <= n <= 100
red_edges.length <= 400
blue_edges.length <= 400
red_edges[i].length == blue_edges[i].length == 2
0 <= red_edges[i][j], blue_edges[i][j] < n

  

解法:BFS

  • 状态:
  • queue中同时保存两者,visited中,防止重复也保存该两个信息。
    • 节点 id
    • 到达当前节点的连线颜色 color
  • 选择:
    • 到达当前节点连线颜色为 red:那么在蓝线集合中,找该节点的下一个节点。
    • 到达当前节点连线颜色为 blue:那么在红线集合中,找该节点的下一个节点。
  • 初始化:节点0:
    • 若n>0,那么一定存在0节点,res[0]=0
    • 红线集合中,有从0出发的连线,那么queue.push({0, blue}) visited.insert({0, blue});
    • 蓝线集合中,有从0出发的连线,那么queue.push({0, red}) visited.insert({0, red});

 

因为BFS的遍历层次从0开始,递增,那么先找到的结果,即为最短。值为level。

 

♻️ 优化:count记录更新过节点后,剩余未更新的节点个数。

若count提前==0,那么所有节点都找到了最近的距离。可停止遍历queue。

 

代码参考:

 1 class Solution {
 2 public:
 3     //state: id, color
 4     //       level
 5     //opt:
 6     //     color == 0 -> blue:1
 7     //     color == 1 -> red :0
 8     vector<int> shortestAlternatingPaths(int n, vector<vector<int>>& red_edges, vector<vector<int>>& blue_edges) {
 9         vector<int> res(n, -1);
10         vector<unordered_map<int, vector<int>>> edges(2);//0:red, 1:blue
11         //initialize edges
12         for(vector<int>& r:red_edges) {
13             edges[0][r[0]].push_back(r[1]);
14             //cout<<"edges[0].back:"<<r[0]<<" Start:"<<edges[0][r[0]].back()<<endl;
15         }
16         for(vector<int>& b:blue_edges) {
17             edges[1][b[0]].push_back(b[1]);
18             //cout<<"edges[1].back:"<<b[1]<<" Start:"<<edges[1][b[0]].back()<<endl;
19         }
20         queue<pair<int, int>> q;//id, color
21         unordered_set<int> visited;
22         if(!edges[1][0].empty()) {
23             q.push({0,0});
24             visited.insert(0*100+0);
25         }
26         if(!edges[0][0].empty()) {
27             q.push({0,1});
28             visited.insert(0*100+1);
29         }
30         if(n>0) res[0]=0;
31         int level = 0;
32         int count = n-1;
33         while(!q.empty() && count!=0) {
34             int sz = q.size();
35             for(int i=0; i<sz; i++) {
36                 auto [id, color] = q.front();
37                 q.pop();
38                 //cout<<"pop:[id,color] "<<id<<","<<color<<" count:"<<count<<endl;
39                 if(res[id]==-1) {
40                     res[id] = level;
41                     count--;
42                 }
43                 color = (color==1)?0:1;
44                 for(int edg:edges[color][id]) {
45                     if(visited.insert(edg*100+color).second) {
46                         q.push({edg, color});
47                     }
48                 }
49             }
50             level++;
51         }
52         return res;
53     }
54 };

 

posted @ 2021-03-18 11:49  habibah_chang  阅读(55)  评论(0编辑  收藏  举报