POJ2110 Mountain Walking(BFS/DFS+二分+枚举区间)

来源:互联网 发布:skype无法连接网络 编辑:程序博客网 时间:2024/06/06 14:07

POJ2110 Mountain Walking(BFS/DFS+二分+枚举区间)

http://poj.org/problem?id=2110

题意: 

        给你一个N*N的网格,并给出网格中每个点的海拔高度,现在要你找出从左上角到右下角那个点的一条路,且这条路所有点中,最高海拔-最低海拔之差最小。输出该最小值。

分析:

        此题与POJ2922基本一致:

http://blog.csdn.net/u013480600/article/details/26097213

        那道题目我用的DFS方法做的,这里我用BFS方法做.

        依然是二分高度差mid且我们枚举的是区间上下界up和low.(mid=up-low)

        对于一个区间[low,up]我们用BFS找,看看能不能找到一条从左上角到右下角的路,且路中走过的所有节点的高度值x都属于区间[low,up].

AC代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int maxn=105;int map[maxn][maxn];int vis[maxn][maxn];int n;int dr[]={-1,1,0,0};//上下左右int dc[]={0,0,-1,1};struct Node{    int r,c;    Node(int r,int c):r(r),c(c){}};bool BFS(int low,int up){    if(map[1][1]<low || map[1][1]>up) return false;    queue<Node> Q;    Q.push(Node(1,1));    vis[1][1]=1;    while(!Q.empty())    {        Node node=Q.front();Q.pop();        int r=node.r,c=node.c;        for(int dir=0;dir<4;dir++)        {            int nr=r+dr[dir] , nc=c+dc[dir];            if(nr>=1&&nr<=n&&nc>=1&&nc<=n&&!vis[nr][nc])            {                vis[nr][nc]=1;                if(map[nr][nc]>=low && map[nr][nc]<=up)                {                    Q.push(Node(nr,nc));                    if(nr==n&&nc==n) return true;      //错误,这句话一定要放在上面那个if里面且把nc写成了nr                }            }        }    }    return false;}bool check(int d){    for(int low=0;low+d<=110;low++)    {        memset(vis,0,sizeof(vis));        if(BFS(low,low+d)) return true;    }    return false;}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)        for(int j=1;j<=n;j++)            scanf("%d",&map[i][j]);    int L=0,R=110;    while(R>L)    {        int mid=(R+L)>>1;        if(check(mid)) R=mid;        else L=mid+1;    }    printf("%d\n",R);    return 0;}


0 0
原创粉丝点击