usaco Overfencing

本文介绍了一种求解二维迷宫中任意点到两个出口最远距离的算法。通过两次宽度优先搜索,分别从两个出口出发,计算每个点到出口的最短路径。最终找出所有可达点中最远的距离。

 题意是给一个二维的迷宫,求任意一个点以最优方案走到出口的步数。求这些点中里出口最远的一个点的步数。

迷宫有两个出口。

 做法是从两个出口各做一遍宽度优先搜索,然后就得到了所有点离当前门口最近的距离。在step数组中记录下最短距离,然后两边宽搜取最小值。

然后遍历step数组,输出最大的一个就是答案。

/*
ID: modengd1
PROG: maze1
LANG: C++
*/
#include <iostream>
#include <stdio.h>
#include <memory.h>
#include <queue>
using namespace std;
char input[210][90];
int step[210][90];
bool vis[210][90];
int W,H;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
struct node
{
    int x,y;
    int T;
    node(int xx,int yy,int tt)
    {
        x=xx;y=yy;T=tt;
    }
    node(){}
};
void BFS(int xx,int yy)
{
    memset(vis,false,sizeof(vis));
    queue<node> Q;
    node now=node(xx,yy,1);
    step[xx][yy]=1;
    vis[xx][yy]=true;
    Q.push(now);
    while(!Q.empty())
    {
        now=Q.front();
        Q.pop();
        node next;
        for(int i=0;i<4;i++)
        {
            next=node(now.x+dx[i]+dx[i],now.y+dy[i]+dy[i],now.T+1);
            if(next.x>=2*H+1||next.x<0||next.y>=2*W+1||next.y<0)
                continue;
            if(input[next.x-dx[i]][next.y-dy[i]]!=' ')
                continue;
            if(vis[next.x][next.y])
                continue;
            vis[next.x][next.y]=true;
            if(step[next.x][next.y]>next.T)
                step[next.x][next.y]=next.T;
            Q.push(next);
        }
    }
}
int main()
{
    freopen("maze1.in","r",stdin);
    freopen("maze1.out","w",stdout);
    memset(step,0x7f,sizeof(step));
    int x1,y1,x2,y2;
    scanf("%d%d",&W,&H);
    getchar();
    for(int i=0;i<2*H+1;i++)
    {
        for(int j=0;j<2*W+1;j++)
        {
            scanf("%c",&input[i][j]);
        }
        getchar();
    }
    for(int i=0;i<2*W+1;i++)
    {
        if(input[0][i]==' ')
            BFS(1,i);
        if(input[2*H][i]==' ')
            BFS(2*H-1,i);
    }
    for(int j=0;j<2*H+1;j++)
    {
        if(input[j][0]==' ')
            BFS(j,1);
        if(input[j][2*W]==' ')
            BFS(j,2*W-1);
    }
    int ans=0;
    for(int i=1;i<2*H;i+=2)
    {
        for(int j=1;j<2*W;j+=2)
            ans=max(ans,step[i][j]);
    }
    cout<<ans<<endl;
    return 0;
}

  

转载于:https://www.cnblogs.com/modengdubai/p/4785047.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值