HDU2612 Find a way(双路广搜BFS)

92 阅读2分钟

题目:

Find a way

**Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11589    Accepted Submission(s): 3771
**
\

Problem 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.\

 

\

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
  
  

 

\

Author

yifenfei

 

\

Source

奋斗的年代

 

\

Recommend

代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int go[4][2]= {{1,0},{-1,0},{0,-1},{0,1}};
int x1,x2,y1,y2;
char map[250][250];
int f1[250][250];//第一个人的步数
int f2[250][250];//第二个人的步数
int vis[250][250];//做标记
int n,m;
struct node
{
    int x,y,s;
};
void bfs(int x,int y,int a[][250])//这里传入了第三个变量
{
    node now,to;
    queue<node>q;
    now.x=x,now.y=y,now.s=0;
    q.push(now);
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        for(int i=0; i<4; i++)//循环四个方向
        {
            int xx=now.x+go[i][0];
            int yy=now.y+go[i][1];
            if(xx>=0&&yy>=0&&xx<n&&yy<m&&map[xx][yy]!='#'&&vis[xx][yy]==0)//判断越界
            {
                vis[xx][yy]=1;//标记走过的
                to.x=xx,to.y=yy,to.s=now.s+1;
                if(map[xx][yy]=='@')
                    a[xx][yy]=to.s;//如果搜到目的地就存一下
                q.push(to);
            }
        }
    }
    return;
}
int main()
{

    while(~scanf("%d%d",&n,&m))
    {
        mem(map,0);
        mem(f1,0);
        mem(f2,0);
        mem(vis,0);//初始化
        for(int i=0; i<n; i++)
        {
            scanf("%s",map[i]);
            for(int j=0; j<m; j++)//寻找两个人的坐标
            {
                if(map[i][j]=='Y')x1=i,y1=j;
                if(map[i][j]=='M')x2=i,y2=j;
            }
        }
        vis[x1][y1]=1;//标记
        bfs(x1,y1,f1);//搜第一个人
        mem(vis,0);//重新初始化
        vis[x2][y2]=1;//标记
        bfs(x2,y2,f2);//搜第二个人
        int min1=99999;//设置一个比较大的值
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
                if(min1>f1[i][j]+f2[i][j]&&f1[i][j]&&f2[i][j])//有值的地方说明有kfc,找出最短的
                    min1=f1[i][j]+f2[i][j];
        printf("%d\n",min1*11);
    }
    return 0;
}


本题的题意是Y,和M两个人要走到“@”这个地方,求的是他们走到哪一个“@”这个用的时间最短

'Y' 表示1所在的初始位置

'M' 表示2所在的初始位置

'#' 该点禁止通行

'.' 该点可通行

'@' KFC

思路是先找出这两个人的坐标,然后把它们到每一个目标点的时间算出来并且存下来(用f1,f2两个数组),最后用循环找出所用时间最短的

\

\