POJ 3170 Knights of Ni(两次BFS啊)

题目链接:http://poj.org/problem?id=3170

Description

Bessie is in Camelot and has encountered a sticky situation: she needs to pass through the forest that is guarded by the Knights of Ni. In order to pass through safely, the Knights have demanded that she bring them a single shrubbery. Time is of the essence,
and Bessie must find and bring them a shrubbery as quickly as possible.

Bessie has a map of of the forest, which is partitioned into a square grid arrayed in the usual manner, with axes parallel to the X and Y axes. The map is W x H units in size (1 <= W <= 1000; 1 <= H <= 1000).

The map shows where Bessie starts her quest, the single square where the Knights of Ni are, and the locations of all the shrubberies of the land. It also shows which areas of the map can be traverse (some grid blocks are impassable because of swamps, cliffs,
and killer rabbits). Bessie can not pass through the Knights of Ni square without a shrubbery.

In order to make sure that she follows the map correctly, Bessie can only move in four directions: North, East, South, or West (i.e., NOT diagonally). She requires one day to complete a traversal from one grid block to a neighboring grid block.

It is guaranteed that Bessie will be able to obtain a shrubbery and then deliver it to the Knights of Ni. Determine the quickest way for her to do so.

Input

Line 1: Two space-separated integers: W and H.

Lines 2..?: These lines describe the map, row by row. The first line describes the most northwest part of the map; the last line describes the most southeast part of the map. Successive integers in the input describe columns of the map from west to east. Each
new row of a map‘s description starts on a new input line, and each input line contains no more than 40 space-separated integers. If W <= 40, then each input line describes a complete row of the map. If W > 40, then more than one line is used to describe a
single row, 40 integers on each line except potentially the last one. No input line ever describes elements of more than one row.

The integers that describe the map come from this set:

0: Square through which Bessie can travel

1: Impassable square that Bessie cannot traverse

2: Bessie‘s starting location

3: Location of the Knights of Ni

4: Location of a shrubbery

Output

Line 1: D, the minimum number of days it will take Bessie to reach a shrubbery and bring it to the Knights of Ni.

Sample Input

8 4
4 1 0 0 0 0 1 0
0 0 0 1 0 1 0 0
0 2 1 1 3 0 4 0
0 0 0 4 1 1 1 0

Sample Output

11

Hint

Explanation of the sample:

Width=8, height=4. Bessie starts on the third row, only a few squares away from the Knights.

Bessie can move in this pattern to get a shrubbery for the Knights: N, W, N, S, E, E, N, E, E, S, S. She gets the shrubbery in the northwest corner and then makes her away around the barriers to the east and then south to the Knights.

Source

USACO 2005 December Silver

PS:

两次BFS,

第一次是找出2到4的最短距离

第二次是找出3到4的最短距离

代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define INF 0x3f3f3f3f
#define MAXN 1000+47
using namespace std;
int w, h;
int s, e;
int G[MAXN][MAXN];
int dis1[MAXN][MAXN], dis2[MAXN][MAXN];
int xx[4] = {0,0,-1,1};
int yy[4] = {1,-1,0,0};
bool vis[MAXN][MAXN];

int MIN(int a, int b)
{
    if(a < b)
        return a;
    return b;
}
void bfs1(int x,int y)
{
    queue<int>q;
    int u = x*w+y;
    vis[x][y]=true;
    q.push(u);
    while(!q.empty())
    {
        u=q.front();
        q.pop();
        x = u/w;
        y = u%w;
        for(int i = 0; i < 4; i++)
        {
            int dx = x + xx[i];
            int dy = y + yy[i];
            if(dx>=0&&dx<h&&dy>=0&&dy<w&&G[dx][dy]!=1&&!vis[dx][dy])
            {
                int v = dx*w+dy;
                q.push(v);
                vis[dx][dy] = true;
                dis1[dx][dy] = dis1[x][y]+1;
            }
        }
    }
}
void bfs2(int x,int y)
{
    queue<int>q;
    int u = x*w+y;
    vis[x][y]=true;
    q.push(u);
    while(!q.empty())
    {
        u=q.front();
        q.pop();
        x = u/w;
        y = u%w;
        for(int i = 0; i < 4; i++)
        {
            int dx = x+xx[i];
            int dy = y+yy[i];
            if(dx>=0&&dx<h&&dy>=0&&dy<w&&G[dx][dy]!=1&&!vis[dx][dy])
            {
                int v = dx*w+dy;
                q.push(v);
                vis[dx][dy] = true;
                dis2[dx][dy] = dis2[x][y]+1;
            }
        }
    }

}
int main()
{
    while(~scanf("%d%d",&w,&h))
    {
        for(int i = 0; i < h; i++)
        {
            for(int j = 0; j < w; j++)
            {
                scanf("%d",&G[i][j]);
                dis1[i][j] = dis2[i][j] = INF;
                if(G[i][j] == 2)
                    s = i*w+j;
                else if(G[i][j] == 3)
                    e = i*w+j;
            }
        }
        memset(vis,false,sizeof(vis));
        dis1[s/w][s%w]=0;
        bfs1(s/w,s%w);//2 到 4
        memset(vis,false,sizeof(vis));
        dis2[e/w][e%w]=0;
        bfs2(e/w,e%w);//3 到 4
        int min_dis = INF;
        for(int i = 0; i < h; i++)
        {
            for(int j = 0; j < w; j++)
            {
                if(G[i][j] == 4)
                {
                    min_dis = MIN(min_dis,dis1[i][j]+dis2[i][j]);
                }
            }
        }
        printf("%d\n",min_dis);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-31 03:07:27

POJ 3170 Knights of Ni(两次BFS啊)的相关文章

POJ 3170(Knights of Ni)(BFS)

题目地址:http://poj.org/problem?id=3170 思路:两次BFS,先从起点到shrubbery点求最短路,再从终点到shrubbery求最短路,枚举shrubbery点,取最小值. #include<cstdio> #include<queue> #include<cstring> #include<iostream> #include<algorithm> #define debu using namespace std

bzoj 1671: [Usaco2005 Dec]Knights of Ni 骑士【bfs】

bfs预处理出每个点s和t的距离d1和d2(无法到达标为inf),然后在若干灌木丛格子(x,y)里取min(d1[x][y]+d2[x][y]) /* 0:贝茜可以通过的空地 1:由于各种原因而不可通行的区域 2:贝茜现在所在的位置 3:骑士们的位置 4:长着贝茜需要的灌木的土地 */ #include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace s

【BZOJ1671】[Usaco2005 Dec]Knights of Ni 骑士 BFS

[Usaco2005 Dec]Knights of Ni 骑士 Description 贝茜遇到了一件很麻烦的事:她无意中闯入了森林里的一座城堡,如果她想回家,就必须穿过这片由骑士们守护着的森林.为了能安全地离开,贝茜不得不按照骑士们的要求,在森林寻找一种特殊的灌木并带一棵给他们.当然,贝茜想早点离开这可怕的森林,于是她必须尽快完成骑士们给的任务,贝茜随身带着这片森林的地图,地图上的森林被放入了直角坐标系,并按x,y轴上的单位长度划分成了W×H(1≤W,H≤1000)块,贝茜在地图上查出了她自己

POJ3170 Bzoj1671 [Usaco2005 Dec]Knights of Ni 骑士

1671: [Usaco2005 Dec]Knights of Ni 骑士 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 281  Solved: 180[Submit][Status][Discuss] Description Bessie is in Camelot and has encountered a sticky situation: she needs to pass through the forest that is guarde

1671: [Usaco2005 Dec]Knights of Ni 骑士

1671: [Usaco2005 Dec]Knights of Ni 骑士 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 254  Solved: 163[Submit][Status][Discuss] Description Bessie is in Camelot and has encountered a sticky situation: she needs to pass through the forest that is guarde

[Usaco2005 Dec]Knights of Ni 骑士

Description Bessie is in Camelot and has encountered a sticky situation: she needs to pass through the forest that is guarded by the Knights of Ni. In order to pass through safely, the Knights have demanded that she bring them a single shrubbery. Tim

BZOJ1671: [Usaco2005 Dec]Knights of Ni

1671: [Usaco2005 Dec]Knights of Ni Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 175  Solved: 107[Submit][Status][Discuss] Description Bessie is in Camelot and has encountered a sticky situation: she needs to pass through the forest that is guarded b

POJ 2942 - Knights of the Round Table(双连通图 Tarjan + 二分判定)

POJ 2942 - Knights of the Round Table(双连通图 Tarjan + 二分判定) ACM 题目地址: POJ 2942 - Knights of the Round Table 题意: 有N个骑士,给出某些骑士之间的仇恨关系,骑士们开会时会围坐在一个圆桌旁.一次会议能够顺利举行,要满足两个条件: 任意相互憎恨的两个骑士不能相邻 开会人数为大于2的奇数 若某个骑士任何会议都不能参加,那么就必须将他踢出,给出骑士之间的仇恨关系,问最少需要踢出多少个骑士? 分析: 把

POJ 2942 Knights of the Round Table (点-双连通分量 + 交叉法染色判二分图)

POJ 2942 Knights of the Round Table 链接:http://poj.org/problem?id=2942 题意:亚瑟王要在圆桌上召开骑士会议,为了不引发骑士之间的冲突,并且能够让会议的议题有令人满意的结果,每次开会前都必须对出席会议的骑士有如下要求: 1. 相互憎恨的两个骑士不能坐在直接相邻的2个位置: 2. 出席会议的骑士数必须是奇数,这是为了让投票表决议题时都能有结果. 如果出现有某些骑士无法出席所有会议(例如这个骑士憎恨所有的其他骑士),则亚瑟王为了世界和