HDU2612-Find a way【双重BFS】

hsj和lsh最近迷上了pokemon go的游戏。在双十一大物期中考试来临之前,他们想抓一只稀有土拨鼠来攒攒人品(因为土拨鼠的刷新地点最近来到了哈工程)
但是由于土拨鼠过于强大,他的雷霆半月斩以及惊天浪涛沙都可以轻松的将他们两击败,但是他们两的合击必杀技流影电光闪以及天羽屠鼠舞可以将土拨鼠打至昏迷状态,并可将其捕获。
但是因为这是款按时间付费的游戏,他们需要尽快捕捉到土拨鼠(即他们两到土拨鼠的时间之和需要最少),因此他们找到了你来帮他们解决这个问题。 规定每走一步需要花费11分钟。

Input

输入存在多组(需使用!=EOF)
每组的第一行有两个整数n,m(2<=n,m<=200)
接下来n行,每行包括m个字符
‘Y’表示hsj所在的位置
‘M’表示lsh所在的位置
‘.’表示可以通过的地方
‘#’表示教学楼即不能走的地方
‘@’表示稀有土拨鼠刷新的地方(地图中存在多只稀有土拨鼠)

Output

对于每组样例输出他们到达土拨鼠刷新点的最小时间总和。
保证每组样例都存在一个土拨鼠刷新点,他们两都能到达 

思路:这题需要注意的地方比较多,我也是wa了好几发。首先我先对Y进行一遍BFS,记录下来到达每个目的地的时间并做标记。然后再对M进行了一遍BFS,同样记录下来可以到达的每个目的地的时间。然后我们对两个人都可以到达的地方,注意:是两个人都可以到达,如果只有一个人可以到达某个地方那是不行的,对符合条件的找最优解就可以了。

参考代码:

#include<set>
#include<map>
#include<stack>
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 2e2 + 10;
char s[maxn][maxn];
bool vis[maxn][maxn];
bool mark[maxn][maxn];
int val[maxn][maxn];
int d[4][2] = {-1, 0, 1, 0, 0, 1, 0, -1};
int n, m;
struct node
{
    int x, y;
    int step;
};
void bfs(int x, int y, int x1, int y1)
{
    memset(vis, false, sizeof(vis));
    memset(mark, false, sizeof(mark));
    queue<node> q1, q2;
    q1.push(node{x, y, 0});
    vis[x][y] = true;
    while(!q1.empty())
    {
        node tmp = q1.front();
        q1.pop();
        if(s[tmp.x][tmp.y] == '@')
        {
            val[tmp.x][tmp.y] = tmp.step;
            vis[tmp.x][tmp.y] = true;
        }
        for(int i = 0; i < 4; ++i)
        {
            int xx = tmp.x + d[i][0];
            int yy = tmp.y + d[i][1];
            if(xx >= 1 && xx <= n && yy >= 1 && yy <= m && !vis[xx][yy] && (s[xx][yy] == '.' || s[xx][yy] == '@'))
            {
                vis[xx][yy] = true;
                q1.push(node{xx, yy, tmp.step + 1});
            }
        }
    }
    memset(vis, false, sizeof(vis));
    q2.push(node{x1, y1, 0});
    vis[x1][y1] = true;
    while(!q2.empty())
    {
        node tmp = q2.front();
        q2.pop();
        if(s[tmp.x][tmp.y] == '@')
        {
            if(val[tmp.x][tmp.y] != -1)
            {
                val[tmp.x][tmp.y] += tmp.step;
                mark[tmp.x][tmp.y] = true;
            }
            vis[tmp.x][tmp.y] = true;
        }
        for(int i = 0; i < 4; ++i)
        {
            int xx = tmp.x + d[i][0];
            int yy = tmp.y + d[i][1];
            if(xx >= 1 && xx <= n && yy >= 1 && yy <= m && !vis[xx][yy] && (s[xx][yy] == '.' || s[xx][yy] == '@'))
            {
                vis[xx][yy] = true;
                q2.push(node{xx, yy, tmp.step + 1});
            }
        }
    }
}

int main()
{
    while(scanf("%d%d", &n, &m) != EOF)
    {
        int x, y, x1, y1;
        for(int i = 1; i <= n; ++i)
        {
            for(int j = 1; j <= m; ++j)
            {
                cin >> s[i][j];
                if(s[i][j] == 'Y')
                    x = i, y = j;
                if(s[i][j] == 'M')
                    x1 = i, y1 = j;
            }
        }
        int ans = inf;
        memset(val, -1, sizeof(val));
        bfs(x, y, x1, y1);
        for(int i = 1; i <= n; ++i)
            for(int j = 1; j <= m; ++j)
                if(s[i][j] == '@' && val[i][j] != -1 && mark[i][j])
                    ans = min(ans, val[i][j]);
        cout << (ll)ans * 11 << endl;
    }

    return 0;
}

 

上一篇:codeforces586B


下一篇:Python 注释,类,属性,方法,继承