HDU 2612 Find a way 多起点 多终点 BFS

N - Find a way
Time Limit:1000MS    Memory Limit:32768KB    64bit IO Format:%I64d & %I64u
SubmitStatusPracticeHDU 2612

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

简单搜索专题的最后一道,多起点多终点的BFS,看起来醉醉嗒,需要多次查询从某个起点到某个点所需要的最短步数,所以打表是一个比较好的选择,也就是进行一次彻底的BFS,计算出起点到达任何一点的最短路径,这就需要我们将这个表建立出来,一个全局的二维数组,以前单终点的时候,都是将步数计数器封装到结构体里,也就是让每个节点记录起点到达自己的步数,当然,也可以把这些数据抽出来,做一个大小和地图相同的二维数组,这样,当进行一次彻底的BFS之后,就得到了起点到达任何一点的最短路径长度,比较起来,前一种方法使代码更加整洁,后一种则通用性更强,可以各取所爱,但是最好不要两种同时出现,除非你想TLE 20次。。。大哭


#include <iostream>
#include <cmath>
#include <stdio.h>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <iomanip>
#include <algorithm>
#include <memory.h>
#define MAX 220
using namespace std;
struct P//不单独记录步数的结构体
{
    int r,c;
    P(int _r,int _c)
    {
        r=_r,c=_c;
    }
    P(){}
};

int n,m;//行,列
char Map[MAX][MAX];
int visit[MAX][MAX];
int min_step;//最小步数
int dirr[]={-1,1,0,0};//方向数组
int dirc[]={0,0,-1,1};
int time_Y[MAX][MAX],time_M[MAX][MAX];//分别记录两个人从起点到达任何一点的最短步数,如果不可到达,标记为-1
P Y,M,temp;//分别记录两个人的起点,以及一个全局temp变量,节省时间

void init()//初始化
{
    memset(time_Y,-1,sizeof(time_Y));
    memset(time_M,-1,sizeof(time_M));
    min_step=9999999;
}


void bfs_Y()//预处理yifenfei 的行走路线信息
{
    queue<P> q;
    q.push(Y);
    time_Y[Y.r][Y.c]=0;
    int r,c;
    int i;
    while(!q.empty())
    {
        temp=q.front();
        q.pop();
        for(i=0;i<4;i++)
        {
            r=temp.r+dirr[i];
            c=temp.c+dirc[i];
            if(r>=0&&r<n&&c>=0&&c<m&&Map[r][c]!='#'&&visit[r][c]==0)
            {
                visit[r][c]=1;
                q.push(P(r,c));
                time_Y[r][c]=time_Y[temp.r][temp.c]+11;
            }
        }
    }
}

void bfs_M()//预处理Ningbo 的路线信息
{
    queue<P> q;
    q.push(M);
    int i,r,c;
    time_M[M.r][M.c]=0;
    while(!q.empty())
    {
        temp=q.front();
        q.pop();
        for(i=0;i<4;i++)
        {
            r=temp.r+dirr[i];
            c=temp.c+dirc[i];
            if(r>=0&&r<n&&c>=0&&c<m&&Map[r][c]!='#'&&visit[r][c]==0)
            {
                visit[r][c]=1;
                q.push(P(r,c));
                time_M[r][c]=time_M[temp.r][temp.c]+11;
            }
        }
    }
}




int main()
{
    int i,j;
    while(cin>>n>>m)//如果用scanf,要加‘~’
    {
        init();
        for(i=0;i<n;i++)
        {
            scanf("%s",Map[i]);
            for(j=0;j<m;j++)
            {
                if(Map[i][j]=='Y')
                {
                    Y.r=i;
                    Y.c=j;
                }
                if(Map[i][j]=='M')
                {
                    M.r=i;
                    M.c=j;
                }
            }

        }
        memset(visit,0,sizeof(visit));
        bfs_Y();
        memset(visit,0,sizeof(visit));
        bfs_M();
        int time1,time2;
        for(i=0;i<n;i++)//遍历整个Map找出所有的KFC
        {
            for(j=0;j<m;j++)
            {
                if(Map[i][j]=='@'&&time_Y[i][j]!=-1&&time_M[i][j]!=-1)
                {
                    time1=time_Y[i][j];
                    time2=time_M[i][j];
                    if((time1+time2)<min_step)
                        min_step=time1+time2;
                }
            }
        }
        printf("%d\n",min_step);
    }
    return 0;
}




你可能感兴趣的:(Way,find,HDU,bfs,a,多起点,多终点,2612)