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]
我以为用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; } };