HDU—2612 Find a way(bfs记录最短路径+遍历求解最佳方案)

Find a way

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


题意:yefenfei和Merceki要在肯德基聚会,要使得他们两去KFC的总时间最小,问最小时间。

解题思路:我们可以这样来解决,记录两个人到地图上所有肯德基的距离,再利双层for循环比对求出最佳方案,详细设计如下:
对于单个人来看,在这块地图中,不只一个KFC,求最短,利用bfs就好,有个细节就是不用退出,直到队空。且未访问的标志也不是设为0,而是置为无穷大,这样有利于接下来的遍历比较。那么两趟bfs即可记录所有点的状态了,接下来通过双重for循环寻找所有KFC的点,利用方程result=min(result,dis[0][i][j])+dis[1][i][j]得出最佳方案。


AC代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<stack>
#include<queue>
#include<cstring>
#include<memory.h>
#include<map>
#include<iterator>
#include<list>
#include<set>
#include<functional>

using namespace std;

const int maxn=202;
const int inf=0x3f3f3f3f;//表示无穷大。
char graph[maxn][maxn];//代表地图。
int dis[2][maxn][maxn];//代表yefenfei和 Merceki.到kfc的距离。其中我们设置无穷大为未访问(便于之后的dp)
int go[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int n,m;//n*m的地图大小。
struct node{
	int x,y;//代表坐标。
}Y,M;//y和m分别代表yefenfei和Merceki的初试位置。
void bfs(node s,int dis[maxn][maxn]){
	queue<node> q;
	node temp,head;
	dis[s.x][s.y]=0;
	q.push(s);
	while(!q.empty()){
		//我们不用判断退出条件,所做的一切只是为了记录到达kfc的距离。
		head=q.front();
		q.pop();
		for(int i=0;i<4;i++){
			temp.x=head.x+go[i][0];temp.y=head.y+go[i][1];
			if(temp.x>=0&&temp.y>=0&&temp.x<n&&temp.y<m&&graph[temp.x][temp.y]!='#'&&dis[temp.x][temp.y]==inf){
				dis[temp.x][temp.y]=dis[head.x][head.y]+1;
				q.push(temp);
			}
		}
	}
}
int main(){
	while(cin>>n>>m){
		int result=inf;
		for(int i=0;i<n;i++){
			cin>>graph[i];
			for(int j=0;j<m;j++){
				//寻找他们的起始位置。
				if(graph[i][j]=='Y'){
					Y.x=i;Y.y=j;
				}
				else if(graph[i][j]=='M'){
					M.x=i;M.y=j;
				}
			}
		}
		memset(dis,inf,sizeof(dis));
		bfs(Y,dis[0]);
		bfs(M,dis[1]);
		//已经获得了所有到达kfc的距离。我们遍历求最短时间。
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(graph[i][j]=='@'){
					result=min(result,dis[0][i][j]+dis[1][i][j]);
				}
			}
		}
		cout<<11*result<<endl;
	}
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hzf0701/article/details/107594856