首先是一个BFS的模板。BFS通过保证到每一个点的路都是最短的来保证到最后的终点也是最短的。如何实现这种保证,那就是通过队列,比如要到达一个需要走三步才能到达的点E,那么先将一步就能到达的A点与B点入队列,从A点进入队列后会得到一个需要两步才能到达的C点,然后A结束后,执行B会得到一个同样需要两步才能得到的D点,现在队列里又剩下了C,D,先对C进行遍历(他不能再回去)发现它可以到E,那么E就是最短三步可以到达,后面对D进行处理发现E已经找到最优解了当然就不去进行寻找了。。。这样不段地按照代价增大的顺序入队,当然最后找到答案的时候那么就是代价最小的了。
int vis[maxn];
bool can(int x,int y){
if(vis[x][y] == -1 && 下一步在题目中是允许走过去的) return true;
else return false;//如果这个点已经访问过了,那么一定是已经从最短的路径过来的了
}
void bfs(){
memset(vis,-1,sizeof(vis));//这里初始化为-1的目的是可以同时判断这里是不是已经得到了最优的解了
建立队列q并且让出发点入队列;
vis[出发点]=0;//不可以再返回出发点了
while(!q.empty()){//只要队列还没有空或者说是还有没有遍历完所有可能的情况那么都还要继续走下去
now=q.front();
q.pop();//取队列的首位,并删除首位
for(列举所有可能的情况){
获取新状态new;
if(can(new)){//如果事先不把所有的情况想好以及判断条件想好,那么后期是很容易错的
if(满足题中所给条件){//
输出答案or更新答案;
return;
}
vis[new] = vis[now]+1;
q.push(new);//新状态入队列
}
}
}
说明还没有找到满足答案的路径;
return;
}
注意BFS是不会像DFS还会试探,所以他在访问完了之后是会直接设置成不能再返回去的,而是直接就永远vis[i]=true了
而其实最短路就是带权值的最短路,或者可以认为BFS就是每一步代价都是1的最短路
bool vis[maxn];//只是用来保证不会返回到上一步
int in[maxn];//用来存储到到达这一步的最小代价
bool can(int x,int y){
if(vis[x][y] == false && 下一步在题目中是允许走过去的) return true;
else return false;//如果这个点已经访问过了,那么一定是已经从最短的路径过来的了
}
void bfs(){
memset(vis,false,sizeof(vis));//这里初始化为-1的目的是可以同时判断这里是不是已经得到了最优的解了
memset(in,-1,sizeof(-1));
建立队列q并且让出发点入队列;
vis[出发点]=0;//不可以再返回出发点了
while(!q.empty()){//只要队列还没有空或者说是还有没有遍历完所有可能的情况那么都还要继续走下去
now=q.front();
q.pop();//取队列的首位,并删除首位
for(列举所有可能的情况){
获取新状态new;
if(can(new)){//如果事先不把所有的情况想好以及判断条件想好,那么后期是很容易错的
int res=in[now]+w[new];
if(in[new]==-1 || res<in[new]){
in[new]=res;
if(vis[new]==false){
q.push(new);//新状态入队列
vis[new]=true;
}
}
}
}
}
找到目标点的最短路径并输出or更新答案;
return;
}