这个题目我只想说一点:
我第一次傻乎乎的遍历每个@, 然后求Y和M到这个点的BFS 的和,再求出所有的和里面的最小值。
这个想法很简单直接,但是会TLE,因为你想想如果 这个地图上的@很多很多的话,你是不是相当于,每个@都是两次bfs , 那么你的bfs次数就太多了!
正确的想法是
整个题,只用做两次bfs ,
第一次 对Y来说, 生成一个Y到所有@的最短距离,
也就是 bfs判断条件种,走到了@。这时候别return , 接着让bfs走下去。
也就是走遍整个地图,从而生成一个,Y到所有@的最短距离的二维数组
第二次对于M , 同理
最后只用判断这俩生成的二维数组,在哪个相同的位置拥有最小的和就行了。
package coding;
import java.io.BufferedInputStream;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class hdu2612 {
static char [][] map;
static int [][] vis;
static int [][] min_y; //保存针对y到所有@的最小距离
static int [][] min_m;
static int [] xx= {0,0,1,-1};
static int [] yy= {1,-1,0,0};
static int m,n;
static int x_y,y_y;
static int x_m,y_m;
static class Node{
int x;
int y;
int step;
}
static void bfs(int x,int y,int who) {
vis = new int[205][205];
Queue<Node> q = new LinkedList<Node>();
Node node = new Node(); node.x= x;node.y=y;node.step=0;
vis[x][y]=1;
q.add(node);
while(!q.isEmpty()) {
Node top = q.poll();
// System.out.println(top.step);
if(map[top.x][top.y]=='@') {
if(who==1) min_y[top.x][top.y]=top.step;
if(who==2) min_m[top.x][top.y]=top.step;
}
for(int i=0;i<4;i++) {
int x2 = top.x+xx[i];
int y2 = top.y+yy[i];
if(x2 >-1 && x2<m && y2>-1 && y2<n &&map[x2][y2]!='#' && vis[x2][y2]==0) {
vis[x2][y2]=1;
Node node2 = new Node(); node2.x= x2;node2.y=y2;node2.step=top.step+1;
q.add(node2);
}
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
while(sc.hasNext()) {
m=sc.nextInt();
n=sc.nextInt();
if(m==0 &&n==0) {
break;
}
map = new char [205][205];
int min=1000000;
for(int i=0;i<m;i++) {
String s = sc.next().toString();
for(int j=0;j<n;j++) {
map[i][j]=s.charAt(j);
if(map[i][j]=='Y') {
x_y=i;
y_y=j;
}
if(map[i][j]=='M') {
x_m=i;
y_m=j;
}
}
}
min_y=new int[205][205];
min_m=new int[205][205];
bfs(x_y, y_y,1);
/*for(int i=0;i<m;i++) {
for(int j=0;j<n;j++) {
System.out.print(min_y[i][j]);
}
System.out.println();
}*/
bfs(x_m, y_m,2);
int res=1000000;
for(int i=0;i<m;i++) {
for(int j=0;j<n;j++) {
if(min_y[i][j]!=0 && min_m[i][j]!=0) {
res= Math.min(res, min_y[i][j]+min_m[i][j]);
}
}
}
System.out.println(res*11);
}
}
}