USACO 2.4 Overfencing maze1 最短路径---BFS

这是我第一次使用队列(queue),第一次用BFS,第一次做最短路径的题(SP),所以来纪念一下。

题目如下:

描述

农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫。幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口。更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找到一条走出迷宫的路。给定迷宫的宽W(1<=W<=38)及长H(1<=H<=100)。 2*H+1行,每行2*W+1的字符以下面给出的格式表示一个迷宫。然后计算从迷宫中最“糟糕”的那一个点走出迷宫所需的步数(就是从最“糟糕”的一点,走出迷宫的最少步数)。(即使从这一点以最优的方式走向最靠近的出口,它仍然需要最多的步数)当然了,牛们只会水平或垂直地在X或Y轴上移动,他们从来不走对角线。每移动到一个新的方格算作一步(包括移出迷宫的那一步)这是一个W=5,H=3的迷宫:

 
+-+-+-+-+-+
|         |
+-+ +-+ + +
|     | | |
+ +-+-+ + +
| |     |  
+-+ +-+-+-+
 

如上图的例子,栅栏的柱子只出现在奇数行或奇数列。每个迷宫只有两个出口。

格式

PROGRAM NAME: maze1

INPUT FORMAT:

(file maze1.in)

第一行: W和H(用空格隔开) 
第二行至第2 * H + 1行:  每行2 * W + 1个字符表示迷宫 

OUTPUT FORMAT:

(file maze1.out)

输出一个单独的整数,表示能保证牛从迷宫中任意一点走出迷宫的最小步数。

SAMPLE INPUT

5 3
+-+-+-+-+-+
|         |
+-+ +-+ + +
|     | | |
+ +-+-+ + +
| |     |  
+-+ +-+-+-+

SAMPLE OUTPUT

9

分析:

就直接从出口处开始BFS,出口处的dis[ 出口 ]=1;然后搜索树每深入一层,该层的dis 等于上一层加一,对于两个出口分别BFS之后,在对每个位置选择距离两个出口更近的dis作为最短路径,最后输出所有点最短路径中最长的那个。

一开始处理输入数据的时候有些麻烦,尤其是找到作为出口的两个点e[0]和e[1]。

代码:

/*
ID: 15659801
LANG: C
TASK: maze1
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct point
{
    int x;
    int y;
} point;
point queue[30000];
int end=-1,start=-1;

char map[205][85];
int w,h;
point e[2];
int cnt;

int di[4]= {-2,0,2,0};
int dj[4]= {0,2,0,-2};
int vis[205][85];
int dis[2][205][85];
int far;
int k;

void scanff(void)
{
    int i,j;
    char xx;
    scanf("%d%d",&w,&h);
    xx=getchar();
    for(i=1; i<=2*h+1; i++)
    {
        for(j=1; j<=2*w+1; j++)
        {
            scanf("%c",&map[i][j]);
        }
        xx=getchar();
    }
    j=1;
    for(i=2;i<=2*h;i+=2)
        if(map[i][j]==' ')
    {
        e[cnt].x=i;
        e[cnt].y=2;
        cnt++;
    }
    j=2*w+1;
    for(i=2;i<=2*h;i+=2)
        if(map[i][j]==' ')
    {
        e[cnt].x=i;
        e[cnt].y=2*w;
        cnt++;
    }
    i=1;
    for(j=2;j<=2*w;j+=2)
        if(map[i][j]==' ')
    {
        e[cnt].x=2;
        e[cnt].y=j;
        cnt++;
    }
    i=2*h+1;
    for(j=2;j<=2*w;j+=2)
        if(map[i][j]==' ')
    {
        e[cnt].x=2*h;
        e[cnt].y=j;
        cnt++;
    }
}
void bfs()
{
    while(start!=end)
    {
        point now=queue[++start];

        int d,nx,ny;
        for(d=0; d<4; d++)
        {
            nx=now.x+di[d];
            ny=now.y+dj[d];
            point next;
            next.x=nx;
            next.y=ny;
            if(vis[nx][ny])
                continue;
            if(nx==now.x&&map[nx][(ny+now.y)/2]==' '&&(ny>=2&&ny<=2*w))
            {
                queue[++end]=next;
                vis[next.x][next.y]=1;
                dis[k][next.x][next.y]=dis[k][now.x][now.y]+1;
            }
            if(ny==now.y&&map[(nx+now.x)/2][ny]==' '&&(nx>=2&&nx<=2*h))
            {
                queue[++end]=next;
                vis[next.x][next.y]=1;
                dis[k][next.x][next.y]=dis[k][now.x][now.y]+1;
            }
        }
    }
}
int main ()
{
    freopen ("maze1.in", "r",stdin);
    freopen ("maze1.out", "w",stdout);
    scanff();

    for(k=0; k<2; k++)
    {
        memset(vis,0,sizeof(vis));
        queue[++end]=e[k];
        dis[k][e[k].x][e[k].y]=1;
        far=1;
        bfs();
    }
    int i,j;
    for(i=2; i<=2*h; i+=2)
        for(j=2; j<=2*w; j+=2)
        {
            if(dis[0][i][j]>dis[1][i][j])
                dis[0][i][j]=dis[1][i][j];
            if(dis[0][i][j]>far)
                far=dis[0][i][j];
        }
    printf("%d\n",far);

    fclose(stdin);
    fclose(stdout);
    exit (0);
}

猜你喜欢

转载自blog.csdn.net/daimaliang/article/details/82110342