zoukankan      html  css  js  c++  java
  • 847. Shortest Path Visiting All Nodes

    问题:

    给定一个图,graph[i]代表节点 i 相连的各个节点。

    求遍历完所有节点,所需要的最小路径花费。

    ⚠️ 注意:可以重复经过同一条边or同一个节点。

    Example 1:
    Input: [[1,2,3],[0],[0],[0]]
    Output: 4
    Explanation: One possible path is [1,0,2,0,3]
    
    Example 2:
    Input: [[1],[0,2,4],[1,3,4],[2],[1,2]]
    Output: 4
    Explanation: One possible path is [0,1,4,2,3]
     
    Note:
    1 <= graph.length <= 12
    0 <= graph[i].length < graph.length
    

      

    解法:BFS

    状态:(我们要找到不能重复操作的状态)

    • 1.当前遍历过的节点->mask(bit)
    • 2.当前位于哪个节点(遍历后的最后一个节点)

    若重复上述两条件后的同一个状态,进行check的话,会出现循环冗余。

    因此我们将上述两个条件合并,作为一个状态Node,作为queue的一个元素。

    同时【条件2】对于queue的展开,进行下一个状态的确定有关,因此必不可少

    对于重复状态的判断,我们用unordered_set,

    由于set的重复判断特性,简单起见,我们将状态Node转化为现存的string,省略实现==的操作。

    而最后所要求的遍历最小路径花费,即为queue展开层数。

    从0层开始,最先找到 target 状态所花费的层数,则为最小路径花费。

    这里,target状态对应于【条件1】的mask为:(1<<graph.size) -1

    代码参考:

     1 class Node {
     2 public:
     3     int mask;//state:1
     4     int v;//state:2
     5     Node(int a, int b) {
     6         mask = a;
     7         v = b;
     8     }
     9     string tostring() {
    10         return to_string(mask)+to_string(v);
    11     }
    12 };
    13 
    14 class Solution {
    15 public:
    16     int shortestPathLength(vector<vector<int>>& graph) {
    17         //state:
    18         //1.node which has been visited
    19         //2.node which is the last one to be visited -> to get next node
    20         //if this state duplicated, we should not check again.
    21         //we choose Node as cell of queue.
    22         int n = graph.size();
    23         queue<Node> q;
    24         unordered_set<string> visited;//for = operation, we use string(existing structure)
    25         int level = 0;
    26         //target mask: ((1<<n)-1)
    27         int target_mask = (1<<n)-1;
    28         //start mask:
    29         for(int i=0; i<n; i++) {
    30             Node cur(1<<i, i);
    31             q.push(cur);
    32             visited.insert(cur.tostring());
    33         }
    34         //traverse queue
    35         while(!q.empty()) {
    36             int sz = q.size();
    37             for(int i=0; i<sz; i++) {
    38                 Node cur = q.front();
    39                 q.pop();
    40                 if(cur.mask==target_mask) return level;
    41                 for(auto nextn:graph[cur.v]) {
    42                     Node nt(cur.mask|(1<<nextn), nextn);
    43                     if(visited.insert(nt.tostring()).second) {
    44                         q.push(nt);
    45                     }
    46                 }
    47             }
    48             level++;
    49         }
    50         return -1;
    51     }
    52 };
  • 相关阅读:
    编写有效事务的指导原则
    ReadUnCommitted与ReadCommitted
    用Delphi 、VB.net以及C#混合编程
    查询未提交事务个数
    输入法的切换问题
    有关数据死锁问题的一篇好文章,一个好博客
    同一连接内事务名只有一个
    无法运行16位应用程序
    查看长时间运行的事务
    在TSQL中使用临时表的注意事项
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14497911.html
Copyright © 2011-2022 走看看