这题跟普通的bfs不一样,因为节点可以重复访问,所以就不能用一个一维的数组来标识节点是否访问,这道题比较巧妙的就是利用二进制的来表示某个节点的当前状态。
或表示前一个状态已经访问过的1加上访问当前节点所对应的1,举个例子,若在f及之前已经访问了0,1节点,即表示的状态为0011,若v是3号节点(1000),则或的结果为1011(即访问v后已经访问了0,1,3号节点)。这样通过判断某个节点的状态是否被访问过就可以避免bfs中出现死循环。
代码如下:
class Solution {
public:
struct p{
int u;
int s;
int len;
p(int uu,int ss,int _len){
u=uu;s=ss;len=_len;
}
};
int shortestPathLength(vector<vector<int>>& graph) {
int size=graph.size();
vector<vector<int> >vis(size,vector<int>(1<<size,0));
queue<p>q;
for(int i=0;i<size;i++)//初始条件是每个节点分别以0001或0010或0100入队列
q.push(p(i,1<<i,0));
while(!q.empty()){
p f=q.front();
q.pop();
for(auto v:graph[f.u]){
int ns=f.s|(1<<v); //
if(!vis[v][ns]){
if(ns==(1<<(size))-1) //目标是全1
return f.len+1;
vis[v][ns]=1;
q.push(p(v,ns,f.len+1));
}
}
}
return 0;
}
};
参考博客:https://blog.csdn.net/fys465253658/article/details/82015182