avatar
fireworks99
keep hungry keep foolish

HDU 2612 Find a way

Description

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.

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2612

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

大意

Y和M两个人要在任意一个KFC见面,求两人路径和中最短的一个

思路

两次BFS求出两人到所有KFC的路径长,再找出和最短的那个

Code

#include <queue>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int inf = 0x3f3f3f3f;

///BFS需要以结构体形式将数据临时存起来以备后来去遍历
///DFS没有要存储的临时数据
///由于DFS要用到递归,我感觉比BFS思想更复杂些
int n, m, ydex, ydey, mdex, mdey;
string s[205];
bool vis[205][205];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

struct node
{
    int x, y, step;
};

int tot;///kfc的a[]辅助,计总个数
struct kfc
{
    int x, y, y_step, m_step, tot_step;
} a[40005];

void kfc_init()
{
    for(int i = 0; i < 205; ++i)
    {
        a[i].y_step = inf;
        a[i].m_step = inf;
    }
}

///BFS擅长于最小(短)值,DFS擅长于连接体(相连)问题
void bfs(int x, int y, bool flag)///写之前一定想好bfs还是dfs
{
    int cnt = 0;///若是DFS(有递归属性),不要在函数里定义啥
    vis[x][y] = 1;
    queue<node> q;
    node now;
    now.x = x;
    now.y = y;
    now.step = 0;
    q.push(now);
    while(q.size())
    {
        now = q.front();
        q.pop();
        if(s[now.x][now.y] == '@')
        {
            cnt++;
            for(int i = 0; i < tot; ++i)
            {
                if(a[i].x == now.x && a[i].y == now.y)
                {
                    if(flag == 0)
                        a[i].y_step = now.step;
                    else
                        a[i].m_step = now.step;
                    break;
                }
            }
            if(cnt == tot)
                return ;
        }

        for(int i = 0; i < 4; ++i)
        {
            int xx = now.x + dx[i];
            int yy = now.y + dy[i];
            if(xx >= 0 && xx < n && yy >= 0 && yy < m && !vis[xx][yy] && s[xx][yy] != '#')
            {
                vis[xx][yy] = 1;
                node nxt;
                nxt.x = xx;
                nxt.y = yy;
                nxt.step = now.step + 1;
                q.push(nxt);
            }
        }
    }
}

int main()
{
//    freopen("00in.txt", "r", stdin);
    while(~scanf("%d%d", &n, &m))
    {
        kfc_init();
        tot = 0;
        memset(vis, 0, sizeof(vis));
        for(int i = 0; i < n; ++i)
            cin >> s[i];

        for(int i = 0; i < n; ++i)
            for(int j = 0; j < m; ++j)
            {
                if(s[i][j] == 'Y')
                {
                    ydex = i;
                    ydey = j;
                }
                if(s[i][j] == 'M')
                {
                    mdex = i;
                    mdey = j;
                }
                if(s[i][j] == '@')
                {
                    a[tot].x = i;
                    a[tot].y = j;
                    tot++;
                }
            }

        bfs(ydex, ydey, 0);
        memset(vis, 0, sizeof(vis));
        bfs(mdex, mdey, 1);

        int ans = inf;
        for(int i = 0; i < tot; ++i)
        {
            a[i].tot_step = a[i].y_step + a[i].m_step;
            if(ans > a[i].tot_step)
                ans = a[i].tot_step;
        }
        cout << ans * 11 << '\n';
    }
    return 0;
}

突然发现DFS比BFS更难以梳理清楚、难实现,因为涉及递归……

相较于DFS,BFS就显得友好多了……

Site by Baole Zhao | Powered by Hexo | theme PreciousJoy