poj 3170 Knights of Ni

15 篇文章 0 订阅

链接:点这里

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.

【题意】

给你一张图,图中包括五种数字,分别表示:

0:可以经过的点
1:不能经过的点
2:你的起点
3:你的终点
4:你需要经过的点

让你找一条从2出发,经过一个4,到达3的最短路。只能上下左右的移动,每次移动一点 花费,问你最小花费。

【分析】

倒过来分析就很简单,把2和3都当作起点,然后两次bfs找出所有到4路径的最短距离,然后对于两条路求和然后取一下min就行了。

【代码】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<sstream>
using namespace std;
#define rep0(i,l,r) for(int i = (l);i < (r);i++)
#define rep1(i,l,r) for(int i = (l);i <= (r);i++)
#define rep_0(i,r,l) for(int i = (r);i > (l);i--)
#define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
#define MS0(a) memset(a,0,sizeof(a))
#define MS_1(a) memset(a,-1,sizeof(a))
#define MSinf(a) memset(a,0x3f,sizeof(a))
#define MSfalse(a) memset(a,false,sizeof(a))
#define inf 0x3f3f3f3f
#define lson i<<1,l,mid
#define rson ((i<<1)|1),mid+1,r
#define uint unsigned int
typedef pair<int,int> pii;
typedef pair<pii,int> piii;
typedef pair<long long,long long> pll;
typedef pair<pll,long long> plll;
#define A first
#define B second
#define pb push_back
#define MK make_pair
#define ll long long
#define eps 1e-8

inline void read1(int &num) {
    char in;
    bool IsN=false;
    in=getchar();
    while(in!='-'&&(in<'0'||in>'9')) in=getchar();
    if(in=='-') {
        IsN=true;
        num=0;
    } else num=in-'0';
    while(in=getchar(),in>='0'&&in<='9') {
        num*=10,num+=in-'0';
    }
    if(IsN) num=-num;
}
inline void read2(int &a,int &b) {
    read1(a);
    read1(b);
}
inline void read3(int &a,int &b,int &c) {
    read1(a);
    read1(b);
    read1(c);
}
inline void read1(ll &num) {
    char in;
    bool IsN=false;
    in=getchar();
    while(in!='-'&&(in<'0'||in>'9')) in=getchar();
    if(in=='-') {
        IsN=true;
        num=0;
    } else num=in-'0';
    while(in=getchar(),in>='0'&&in<='9') {
        num*=10,num+=in-'0';
    }
    if(IsN) num=-num;
}
inline void read2(ll &a,ll &b) {
    read1(a);
    read1(b);
}
inline void read3(ll &a,ll &b,ll &c) {
    read1(a);
    read1(b);
    read1(c);
}
inline void read1(double &num) {
    char in;
    double Dec=0.1;
    bool IsN=false,IsD=false;
    in=getchar();
    while(in!='-'&&in!='.'&&(in<'0'||in>'9'))
        in=getchar();
    if(in=='-') {
        IsN=true;
        num=0;
    } else if(in=='.') {
        IsD=true;
        num=0;
    } else num=in-'0';
    if(!IsD) {
        while(in=getchar(),in>='0'&&in<='9') {
            num*=10;
            num+=in-'0';
        }
    }
    if(in!='.') {
        if(IsN) num=-num;
        return ;
    } else {
        while(in=getchar(),in>='0'&&in<='9') {
            num+=Dec*(in-'0');
            Dec*=0.1;
        }
    }
    if(IsN) num=-num;
}
inline void read2(double &a,double &b) {
    read1(a);
    read1(b);
}
inline void read3(double &a,double &b,double &c) {
    read1(a);
    read1(b);
    read1(c);

}
///---------------------------------------------------------------------------------
const int maxm = 1000;
int mat[maxm][maxm];
int dis[2][maxm][maxm];
int n,m;
int sx1,sy1,sx2,sy2;
int changex[] = {0,0,1,-1};
int changey[] = {1,-1,0,0};
struct P {
    int x,y,value;
    P() {}
    P(int _x,int _y,int _value) {
        x = _x;
        y = _y;
        value = _value;
    }
};
void bfs(int x,int y,int now) {
    dis[now][x][y] = 0;
    queue<P>q;
    q.push(P(x,y,0));
    while(!q.empty()) {
        P p = q.front();
        q.pop();
        rep0(i,0,4) {
            P pp;
            pp.x = p.x+changex[i];
            pp.y = p.y+changey[i];
            if(pp.x<0||pp.x>n) continue;
            if(pp.y<0||pp.y>m) continue;
            if(mat[pp.x][pp.y]==1) continue;
            pp.value = p.value+1;
            if(pp.value<dis[now][pp.x][pp.y]) {
                dis[now][pp.x][pp.y] = pp.value;
                q.push(pp);
            }
        }
    }
}
int main() {
//    freopen("in.txt","r",stdin);
    read2(m,n);
    sx1 = -1,sy1 = -1;
    rep0(i,0,n) rep0(j,0,m) {
        dis[0][i][j] = inf;
        dis[1][i][j] = inf;
        read1(mat[i][j]);
        if(mat[i][j]==2)
            sx1 = i,sy1 = j;
        else if(mat[i][j]==3)
            sx2 = i,sy2 = j;
    }
    bfs(sx1,sy1,0);
    bfs(sx2,sy2,1);
    int ans = inf;
    rep0(i,0,n) rep0(j,0,m) {
        if(mat[i][j]==4)
            ans = min(ans,dis[0][i][j]+dis[1][i][j]);
    }
    printf("%d\n",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zuhiul

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值