【 HDU 2612】 Find a way 双BFS

5 篇文章 0 订阅

                              HDU 2612   Find a way

Pass a year learning in Hangzhou, yifenfei arrival hometown Ningbo at finally. Leave Ningbo one year, yifenfei have many people to meet. Especially a good friend Merceki. 
Yifenfei’s home is at the countryside, but Merceki’s home is in the center of city. So yifenfei made arrangements with Merceki to meet at a KFC. There are many KFC in Ningbo, they want to choose one that let the total time to it be most smallest. 
Now give you a Ningbo map, Both yifenfei and Merceki can move up, down ,left, right to the adjacent road by cost 11 minutes. 

Input

The input contains multiple test cases. 
Each test case include, first two integers n, m. (2<=n,m<=200). 
Next n lines, each line included m character. 
‘Y’ express yifenfei initial position. 
‘M’    express Merceki initial position. 
‘#’ forbid road; 
‘.’ Road. 
‘@’ KCF 

Output

For each test case output the minimum total time that both yifenfei and Merceki to arrival one of KFC.You may sure there is always have a KFC that can let them meet.

Sample Input

4 4
Y.#@
....
.#..
@..M
4 4
Y.#@
....
.#..
@#.M
5 5
Y..@.
.#...
.#...
@..M.
#...#

Sample Output

66
88
66

题意:就是M和Y好久没见了,现在他们两要在某一个KFC见面,每走一格花费11分钟,'@' 代表KFC,'#' 代表障碍物,'.' 代表道路,问你最短的时间是多少,我们可以这样考虑,既然要求M和Y到某个KFC的最少用时,我们可以分别使用BFS算出M,Y到每一个KFC的最少用时,然后遍历,找出最小值,典型的双BFS问题,但有很多细节问题需要注意。

题解:当数据又有数字,又有字符,一定要考虑吃掉换行呀,笔者今天为此,把代码写了又删,删了又写,最后才发现没有吃掉最开始两个数字后面的换行,血淋淋的教训。

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=200+7;
const int INF=0x7fffffff;
char map[maxn][maxn];   //地图
bool vis[maxn][maxn];   //标志数组 判断当前位置是否被访问
int step1[maxn][maxn];   //存第一次bfs的最少用时
int step2[maxn][maxn];   //存第二次bfs的最少用时
int n,m,x1,y1,x2,y2;
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};   //上 下 左 右 四个方向
struct node{                    //结点 某一个位置和走到当前位置的最短用时
    int x,y,cnt;
    node(int x=0,int y=0,int cnt=0):x(x),y(y),cnt(cnt){}
};
int check(int x,int y)         //判断当前结点是否可前进
{
    if(x>=1&&x<=n&&y>=1&&y<=m&&map[x][y]!='#')return 1;
    else return 0;
}
int min(int x,int y)       //手写最小值函数
{
    if(x>y)return y;
    else return x;
}
void bfs1(int x,int y)      //第一次bfs
{
    memset(vis,false,sizeof(vis));
    memset(step1,-1,sizeof(step1));
    queue<node>q1;
    node now,next;
    now.x=x;
    now.y=y;
    now.cnt=0;
    q1.push(now);
    vis[now.x][now.y]=true;
    while(!q1.empty()){
        now=q1.front();
        q1.pop();
        if(map[now.x][now.y]=='@'){
            step1[now.x][now.y]=now.cnt;
        }
        for(int i=0;i<4;i++){
            next.x=now.x+dir[i][0];
            next.y=now.y+dir[i][1];
            if(check(next.x,next.y)&&!vis[next.x][next.y]){
                next.cnt=now.cnt+1;
                q1.push(next);
                vis[next.x][next.y]=true;
            }
        }
    }
}
void bfs2(int x,int y)        //第二次bfs
{
    memset(vis,false,sizeof(vis));
    memset(step2,-1,sizeof(step2));
    queue<node>q2;
    node now,next;
    now.x=x;
    now.y=y;
    now.cnt=0;
    q2.push(now);
    vis[now.x][now.y]=true;
    while(!q2.empty()){
        now=q2.front();
        q2.pop();
        if(map[now.x][now.y]=='@'){
            step2[now.x][now.y]=now.cnt;
        }
        for(int i=0;i<4;i++){
            next.x=now.x+dir[i][0];
            next.y=now.y+dir[i][1];
            if(check(next.x,next.y)&&!vis[next.x][next.y]){
                next.cnt=now.cnt+1;
                q2.push(next);
                vis[next.x][next.y]=true;
            }
        }
    }
}
int main()
{
    while(scanf("%d %d",&n,&m)==2){
        getchar();               //血的教训 读取字符串一定要记得吃掉换行 改了一天的bug
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%c",&map[i][j]);
                if(map[i][j]=='Y'){
                    x1=i;
                    y1=j;
                }
                else if(map[i][j]=='M'){
                    x2=i;
                    y2=j;
                }
            }
        getchar();
        }
    bfs1(x1,y1);
    bfs2(x2,y2);
    int minn=INF;
    for(int i=1;i<=n;i++){             //遍历数组 找到最少用时
        for(int j=1;j<=m;j++){
            if(map[i][j]=='@'&&step1[i][j]+step2[i][j]>-1){
                minn=min(minn,step1[i][j]+step2[i][j]);
            }
        }
    }
    printf("%d\n",minn*11);
}
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值