BFS基础题 杭电2612 Find a way 1252 Hike on a Graph

来源:互联网 发布:之二虫又何知的之 编辑:程序博客网 时间:2024/06/06 21:34

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
题目有点难理解:有三个棋子,分别由三位玩家控制,游戏的目的是使所有棋子到达同一个位置。约束条件是:

原创粉丝点击