poj 3182 The Grove bfs

思路:如果要围绕一圈,必须经过一条竖线上的一点,把竖线左端封住,bfs一次,枚举点,再把竖线右端封住,再bfs回起点。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=5e1+9,inf=1e9;
char a[maxn][maxn],now[maxn][maxn];
int dist[maxn][maxn],d[maxn][maxn],quex[1111111],quey[1111111];
int n,m;
void init()
{
    memset(a,0,sizeof(a));
    memset(now,0,sizeof(now));
}


void bfs(int x,int y,int dist[maxn][maxn])
{
    bool visit[maxn][maxn];
    memset(dist,50,sizeof(dist));
    memset(visit,0,sizeof(visit));
    dist[x][y]=0;
    int front=1,end=0;
    quex[++end]=x;
    quey[end]=y;
    visit[x][y]=1;
    while(front<=end)
    {
        int nowx=quex[front],nowy=quey[front++];
        int tox,toy;
        for(int i=-1;i<=1;i++)
        for(int j=-1;j<=1;j++)
        {
            tox=nowx+i;
            toy=nowy+j;
            if(tox>n||tox<1) continue;
            if(toy>m||toy<1) continue;
            if(now[tox][toy]=='X') continue;
            if(!visit[tox][toy])
            {
                visit[tox][toy]=1;
                dist[tox][toy]=dist[nowx][nowy]+1;
                quex[++end]=tox;
                quey[end]=toy;
            }
        }
    }
}

int main()
{
//    freopen("in.txt","r",stdin);
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        init();
        int sx,sy,lowx,lowy;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            char tmp;
            tmp=getchar();
            if(tmp==' '||tmp=='
')  j--;
            else a[i][j]=tmp;
            if(tmp=='*') sx=i,sy=j;
        }
        for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        if(a[i][j]=='X')
        {
            lowx=i;
            lowy=j;
            i=n+1;
            break;
        }
        for(int i=1;i<=n;i++) strcpy(now[i]+1,a[i]+1);
        for(int i=lowx;i>=1;i--)
        now[i][lowy-1]='X';
        bfs(sx,sy,dist);

        int upx=lowx,upy;
        for(int j=m;j>=1;j--)
        if(a[upx][j]=='X')
        {
            upy=j;
            break;
        }

        for(int i=1;i<=n;i++) strcpy(now[i]+1,a[i]+1);
        for(int i=upx;i>=1;i--)
        now[i][upy+1]='X';

        int ans=inf;
        for(int i=lowx-1;i>=1;i--)
        {
            bfs(i,lowy,d);
            ans=min(ans,dist[i][lowy]+d[sx][sy]);
        }
        cout<<ans<<endl;
    }
    return 0;
}


原文地址:https://www.cnblogs.com/keanuyaoo/p/3353220.html