HDU2612 Find a way (BFS的应用)

题意

圣诞节要到了,坤神和瑞瑞这对基佬想一起去召唤师大峡谷开开车。百度地图一下,发现周围的召唤师大峡谷还不少,这对基佬纠结着,该去哪一个。。。坤神:我要去左边的这个(因为离自己比较近 哈哈~)。。瑞瑞:我要去右边的这个(因为离自己比较近 嘿嘿~) ……..这对基佬闹矛盾了,开车有危险了! 为了不让他们去召唤师大峡谷坑人,riot决定让他们去X召唤师大峡谷,保证他俩所走的路程和最短。每走一个点需要花费11分钟,输出他们一共花费多少时间(最短时间噢)
Input
多组测试数据

每组数据,开始一行n,m (2<=n,m<=200)

接下来是个n x m的矩阵

‘Y’ 表示坤神所在的初始位置

‘M’ 表示瑞瑞所在的初始位置

‘#’ 该点禁止通行

‘.’ 该点可通行

‘@’ 召唤师大峡谷

Output
每组测试数据,输出坤神和瑞瑞到达同一个召唤师大峡谷所花费的最短时间。

Sample Input
4 4
Y.#@
….
.#..
@..M
4 4
Y.#@
….
.#..
@#.M
5 5
Y..@.
.#…
.#…
@..M.
#…#
Sample Output
66
88
66
Hint
对于第一组样例,坤神和瑞瑞去矩阵(4,1) 这个召唤师大峡谷,耗费的时间为 3 * 11 + 3 * 11 = 66, 去矩阵(1,4)这个召唤师大峡谷,耗费的时间为 5 * 11 + 3 * 11 = 88 。所以,最终答案:66。

解题

用d[i][j]表示Y到第i行第j列所需的时间。用p[i][j]表示M到第i行第j列所需时间。因为每条边的权值都是1,故
进行常规的BFS并维护d数组和p数组值即可。枚举所有的@字符的d值和p值,取和最小的即可。

AC代码

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;

const int maxn=220;
int n,m;
char s[maxn][maxn];
int getid(int x,int y)
{
    return (x-1)*m+y;
}
int d[maxn][maxn];
int p[maxn][maxn];
struct node
{
    int x,y,t;
    node(int x,int y,int t):x(x),y(y),t(t){}
};
bool vis[maxn][maxn];
int dir[4][2]={0,1,0,-1,-1,0,1,0};
bool valid(int x,int y)
{
    return x>=0 && x<n && y>=0 && y<m && !vis[x][y] && s[x][y]!='#';
}
void bfs(char c,int u,int v)
{
    queue<node> Q;
    if(c=='Y')
        memset(d,0x3f,sizeof(d));
    if(c=='M')
        memset(p,0x3f,sizeof(p));
    memset(vis,false,sizeof(vis));
    Q.push(node(u,v,0));
    while(!Q.empty())
    {
        node now=Q.front();Q.pop();
        int x=now.x,y=now.y,t=now.t;
        for(int i=0;i<4;i++)
        {
            int fx=x+dir[i][0],fy=y+dir[i][1];
            if(!valid(fx,fy)) continue;
            vis[fx][fy]=true;
            if(c=='Y') d[fx][fy]=t+1;
            else p[fx][fy]=t+1;
            Q.push(node(fx,fy,t+1));
        }

    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0;i<n;i++)
            scanf("%s",s[i]);
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
        {
            if(s[i][j]=='Y') bfs('Y',i,j);
            else if(s[i][j]=='M') bfs('M',i,j);
        }
        int ans=INF;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            if(s[i][j]=='@')
            ans=min(ans,d[i][j]+p[i][j]);
        printf("%d\n",ans*11);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37685156/article/details/80747821