[kuangbin]专题一 简单搜索 Find a way HDU - 2612【BFS】

【题目描述】
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.
经过一年的杭州学习,yifenfei终于来到了家乡宁波。离开宁波一年,yifenfei有很多人要见,尤其是一个好朋友Merceki。
yifenfei的家在农村,但Merceki的家在市中心。于是,yifenfei和Merceki安排在肯德基见面。宁波有很多肯德基,他们想选择一个让总时间最短的。
现在给你一张宁波地图,yifenfei和Merceki都可以上下左右移动到相邻的道路上通过花费11分钟。

【输入】
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.
‘@’ KFC
输入包含多个测试样例
每个样例包括开始两个整数n和m,(2<=n,m<=200)
后面n行,每行m个字符
'Y’表示yifenfei的初始位置
‘M’表示Merceki的初始位置
‘#’表示禁止通行的道路
‘.'表示道路
‘@’表示肯德基

【输出】
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.
对于每个测试用例,输出Yifenfi和Merceki到KFC之一的最短总时间。您可以肯定,总有一个肯德基可以让他们见面。

【样例输入】
4 4
Y.#@

.#…
@…M
4 4
Y.#@

.#…
@#.M
5 5
Y…@.
.#…
.#…
@…M.
#…#

【样例输出】
66
88
66

题目链接:https://cn.vjudge.net/problem/HDU-2612

分别对两个人的路线进行bfs,最后找两个人加起来step最小的KFC

代码如下:

#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
static const int MAXN=200;
static const int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
char mp[MAXN+10][MAXN+10];
int stepsum[MAXN+10][MAXN+10];
bool vis1[MAXN+10][MAXN+10];
bool vis2[MAXN+10][MAXN+10];
int n,m;
struct Node{
    int x,y;
    int step;
};
void yifenfei_bfs(Node node)
{
    queue<Node> Q;
    vis1[node.x][node.y]=true;
    Q.push(node);
    while(!Q.empty())
    {
        Node now=Q.front();
        Q.pop();
        if(mp[now.x][now.y]=='@')
            stepsum[now.x][now.y]+=now.step;
        for(int i=0;i<4;i++)
        {
            Node next;
            next.x=now.x+dx[i];
            next.y=now.y+dy[i];
            next.step=now.step+1;
            if(1<=next.x && next.x<=n && 1<=next.y && next.y<=m && mp[next.x][next.y]!='#' && !vis1[next.x][next.y])
            {
                vis1[next.x][next.y]=true;
                Q.push(next);
            }
        }
    }
}
void Merceki_bfs(Node node)
{
    queue<Node> Q;
    vis2[node.x][node.y]=true;
    Q.push(node);
    while(!Q.empty())
    {
        Node now=Q.front();
        Q.pop();
        if(mp[now.x][now.y]=='@')
            stepsum[now.x][now.y]+=now.step;
        for(int i=0;i<4;i++)
        {
            Node next;
            next.x=now.x+dx[i];
            next.y=now.y+dy[i];
            next.step=now.step+1;
            if(1<=next.x && next.x<=n && 1<=next.y && next.y<=m && mp[next.x][next.y]!='#' && !vis2[next.x][next.y])
            {
                vis2[next.x][next.y]=true;
                Q.push(next);
            }
        }
    }
}
int main()
{
    std::ios::sync_with_stdio(false);
    std:cin.tie(0),cout.tie(0);
    while(cin>>n>>m)
    {
        memset(stepsum,0,sizeof(stepsum));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cin>>mp[i][j];
        memset(vis1,false,sizeof(vis1));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(mp[i][j]=='Y')
                    yifenfei_bfs(Node{i,j,0});
        memset(vis2,false,sizeof(vis2));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(mp[i][j]=='M')
                    Merceki_bfs(Node{i,j,0});
        int minstep=0x7fffffff;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if(mp[i][j]=='@' && vis1[i][j] && vis2[i][j])//坑点,WA了好几次,此处需要判断两个人是否都到达过这个KFC,为了方便故分开写
                    minstep=min(minstep,stepsum[i][j]);
            }
        cout<<minstep*11<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值