• 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 };
  • 相关阅读:
    PHP里json_encode()与json_decod()区别
    数组进行排序
    tp5利用自带上传类实现单个文件与多文件上传
    mkdir() Permission denied 报错问题
    如何快速熟悉新项目的代码?
    Tp5自定义路径写入日志
    spring解决循环依赖
    spring注解的使用
    ssm的整合
    编程知识总结
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14554841.html
Copyright © 2020-2023  润新知