Description
Input
Output
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; }