访问C ++中所有节点的最短路径
假设我们有一个带有N个节点的无向连通图,这些节点被标记为0、1、2,...,N-1。图的长度将为N,并且仅当节点i和j连接时,j才与列表graph[i]中的i不完全相同。我们必须找到访问每个节点的最短路径的长度。我们可以在任何节点处开始和停止,可以多次访问节点,并且可以重用边缘。
因此,如果输入类似于[[1],[0,2,4],[1,3,4],[2],[1,2]],则输出将为4。路径为[0,1,4,2,3]。
为了解决这个问题,我们将遵循以下步骤-
定义一个队列
n:=图的大小
要求:=2^(n-1)
定义一张映射
对于初始化i:=0,当i<n时,更新(将i增加1),执行-
将{0OR(2^i),i}插入q
如果n与1相同,则-
返回0
对于初始化lvl:=1,当非q为空时,更新(将lvl增加1),执行-
定义一个数组curr=q的前元素
从q删除元素
对于初始化i:=0,当i<graph[curr[1]]的大小时,更新(将i增加1),执行
忽略以下部分,跳至下一个迭代
返回lvl
u:=graph[curr[1],i]
newMask:=(curr[0]或2^u)
如果newMask与req相同,则-
如果visited[u]的呼叫计数(newMask),则-
将newMask插入访问过的网站[u]
将{newMask,u}插入q
sz:=q的大小
当sz为非零值时,请在每次迭代中将sz减1,然后执行-
返回-1
让我们看下面的实现以更好地理解-
示例
#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
cout << "[";
for(int i = 0; i<v.size(); i++){
cout << v[i] << ", ";
}
cout << "]"<<endl;
}
class Solution {
public:
int shortestPathLength(vector<vector<int> >& graph){
queue<vector<int> > q;
int n = graph.size();
int req = (1 << n) - 1;
map<int, set<int> > visited;
for (int i = 0; i < n; i++) {
q.push({ 0 | (1 << i), i });
}
if (n == 1)
return 0;
for (int lvl = 1; !q.empty(); lvl++) {
int sz = q.size();
while (sz--) {
vector<int> curr = q.front();
q.pop();
for (int i = 0; i < graph[curr[1]].size(); i++) {
int u = graph[curr[1]][i];
int newMask = (curr[0] | (1 << u));
if (newMask == req)
return lvl;
if (visited[u].count(newMask))
continue;
visited[u].insert(newMask);
q.push({ newMask, u });
}
}
}
return -1;
}
};
main(){
Solution ob;
vector<vector<int>> v = {{1},{0,2,4},{1,3,4},{2},{1,2}};
cout << (ob.shortestPathLength(v));
}输入值
{{1},{0,2,4},{1,3,4},{2},{1,2}}输出结果
4