BFS与DFS简单对比
DFS适合将所有的全都遍历一遍,就像之前的博客中的两道DFS基础题,比如最多可以走几步,所有的连通区域个数,这些都需要全部遍历完才能知道。
而BFS,比如求最短的距离,可以直接宽度优先搜索目的地,不需要全都遍历一遍才可以求最短路径。当然,BFS也可以用于全部遍历之后才得出最终解的题目。不过,BFS不适合求解诸如最多可以走几步这样的题目。
下面是杭电2612的链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2612
原题大意:有两个人,分别在城市的不同地方,他们约好在KFC见面(城市里有多家KFC),有些路不能走有些可以走,求出一个KFC的位置,使他们两人走路的长度之和最短。
分析:这是求两人的长度之和最短,所以针对每个人,需要分别求出到每个KFC的最短距离,然后相加求出最短和。这题只能用BFS进行搜索,因为每次搜到KFC的话,那么肯定就是最短距离。但是DFS就不能得出最短距离了,因为他需要比较所有搜索到该目的地的所有距离,然后取得最短值,但是这些所有的距离是没办法得出的。
下面是代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
int m, n;
char a[205][205];//存储元素信息
int direction[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };
int visited[205][205];//记录节点是否被访问过
int dis[205][205][2]; //记录两个人到每个位置的最短距离,三维数组
int flag; //记录是第一个人还是第二个人的最短距离
struct node{ //定义结构体是为了把每个节点入队列,而且可以记录每个节点的步数
int x, y, step;
node(int x0, int y0, int step0){ x = x0; y = y0; step = step0; }
};
void bfs(int x, int y){
visited[x][y] = 1;
queue<node> q;
q.push(node(x, y, 0));
while (!q.empty()){
node u = q.front(); //先取出队首元素,再pop出去
q.pop();
int nx, ny;
for (int i = 0; i < 4; i++){
nx = direction[i][0] + u.x; //要注意,这里是u.x,不是x
ny = direction[i][1] + u.y;
if (nx < n&&nx >= 0 && ny < m&&ny >= 0 && visited[nx][ny] == 0 && a[nx][ny] != '#'){
visited[nx][ny] = 1;
dis[nx][ny][flag] = u.step + 1; //重点!每次将step加1
q.push(node(nx, ny, u.step + 1));
}
}
}
}
int main(){
//int m, n; //啊啊啊,找了好久错误,原来是在这里又定义了个m,n,它就不是全局变量了,所以一直进不去BFS
//所以,一定要注意全局变量在外面设置,只在main函数赋值
int x1, y1, x2, y2; //分别存储两人的初始位置
while (scanf("%d%d", &n, &m) != EOF){
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
cin >> a[i][j];
if (a[i][j] == 'Y') { x1 = i; y1 = j; }
if (a[i][j] == 'M') { x2 = i; y2 = j; }
}
}
memset(dis, 0x1f, sizeof(dis));
memset(visited, 0, sizeof(visited));
flag = 0;
bfs(x1, y1);
memset(visited, 0, sizeof(visited));
flag = 1;
bfs(x2, y2);
//搜索完成之后,就得到了两个人到所有点的最短距离
int mins = 0x1f1f1f1f;
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
if (a[i][j] == '@'){
mins = min(mins, dis[i][j][0] + dis[i][j][1]);
}
}
}
cout << mins*11 << endl;
}
return 0;
}
杭电1252
原题链接: http://acm.hdu.edu.cn/showproblem.php?pid=1252
题目有点难理解:有三个棋子,分别由三位玩家控制,游戏的目的是使所有棋子到达同一个位置。约束条件是: