847. 访问所有节点的最短路径 力扣(困难) bfs+状态压缩 tupe 做不来

847. 访问所有节点的最短路径

存在一个由 n 个节点组成的无向连通图,图中的节点按从 0 到 n - 1 编号。

给你一个数组 graph 表示这个图。其中,graph[i] 是一个列表,由所有与节点 i 直接相连的节点组成。

返回能够访问所有节点的最短路径的长度。你可以在任一节点开始和停止,也可以多次重访节点,并且可以重用边。

示例 1:

输入:graph = [[1,2,3],[0],[0],[0]]

输出:4

解释:一种可能的路径为 [1,0,2,0,3]

题解:https://leetcode-cn.com/problems/shortest-path-visiting-all-nodes/solution/gtalgorithm-tu-jie-fa-ba-hardbian-cheng-v5knb/

我以为用dfs,但是想不出来,对于回来的点,路径长度应该如何记录,那和下一次探路,感觉矛盾,不可行。

tuple用法:

queue<tuple<int,int,int>> Q;     // 构造  尖括号
auto [id,state,dis]=Q.front();   // 取值  中括号
Q.push({i,nextstate,dis+1});     // 插入  花括号,类似vector<vector<int>> a;  a.push_back({ , , ... , })  类似

代码: 

class Solution {
public:
 
    int shortestPathLength(vector<vector<int>>& graph) { 
     int n=graph.size();
     vector<vector<bool>> vis(n,vector<bool>(1<<n));   // 每个节点,都有2^n个状态,也就是有2^n机会可以访问
     queue<tuple<int,int,int>> Q;  // 三元组(节点编号,当前节点的压缩状态,步长)

     for(int i=0;i<n;i++) 
     {
         Q.push({i,1<<i,0});    // tuple原来如此传入,花括号{}
         vis[i][1<<i]=1;
     }
     while(!Q.empty())
     {
         auto [id,state,dis]=Q.front();   // 值用中括号[]
         Q.pop();

         if (state==(1<<n)-1)  return dis;

         for(auto i:graph[id])
         {
             int nextstate=state|(1<<i);
             if(vis[i][nextstate]) continue;
             vis[i][nextstate]=1;
             Q.push({i,nextstate,dis+1});
         }  
     }
     return 0;
    }
};
原文地址:https://www.cnblogs.com/stepping/p/15109023.html