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 };

 

posted @ 2021-03-08 09:14  habibah_chang  阅读(56)  评论(0编辑  收藏  举报