2016HUAS暑假集训训练题 D

F                                                                                                                        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

本题主要为bfs双向查找,用bfs查找也行,记录两个人到@的时间 最后再求最短时间 但用c++容易超时,用java只用了800多ms
附上AC代码:
import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.Scanner;
public class Main {
	static int queue[] = new int[40005];
	static int queue1[] = new int[40005];
	static int top;
	static int under;
	static int top1;
	static int under1;
	static int dir[][] = { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } };
	static String a[] = new String[205];
        public static void main(String[] args) throws IOException, ArrayIndexOutOfBoundsException {
		Scanner s = new Scanner(new BufferedInputStream(System.in));
		int x2;
		int y2;
		int px, py, x, start = 0, en = 0, y, v, v2;
		int px1;
		int py1;

		while (s.hasNext()) {
			x = s.nextInt();
			y = s.nextInt();
			int visit1[][] = new int[x][y];
			int visit[][] = new int[x][y];
			for (int i = 0; i < x; i++) {            //输入地图
				a[i] = s.next();
				for (int j = 0; j < y; j++) {

					if (a[i].charAt(j) == 'Y')   //Y的位置
						start = i * y + j;
					if (a[i].charAt(j) == 'M')   //M的位置
						en = i * y + j;
				}
			}
                         //对Y进行bfs搜索  记录的到各点的距离
			top = -1;
			under = 0;
			for (int i = 0; i < x; i++) {

				for (int j = 0; j < y; j++) {
					visit[i][j] = 0;
      			}
			}
			visit[start / y][start % y] = 1;
			queue_push(start);
			int x1 = start / y, y1 = start % y;  //数组的下标
         		while (under <= top) {
				v = queue_pop();
				x1 = v / y;
				y1 = v % y;
				for (int i = 0; i < 4; i++) {
					px = x1 + dir[i][0];
					py = y1 + dir[i][1];
					if (px >= 0 && px < x && py < y && py >= 0 && visit[px][py] == 0 && a[px].charAt(py) != '#') {  //找到符合条件的点
						queue_push(px * y + py);
						visit[px][py] = visit[x1][y1] + 1;            //令 visit为前一个加一  表示Y到此点的距离
					}
				}
			}
                      //对M进行bfs搜索   具体和Y搜索一致  不再重复
			top1 = -1;
			under1 = 0;
			for (int i = 0; i < x; i++) {

				for (int j = 0; j < y; j++) {
					visit1[i][j] = 0;
             			}
			}
			visit1[en / y][en % y] = 1;
			queue1_push(en);
			x2 = en / y;
			y2 = en % y;
			while (under1 <= top1) {
				v2 = queue1_pop();
				x2 = v2 / y;
				y2 = v2 % y;
				for (int i = 0; i < 4; i++) {
					px1 = x2 + dir[i][0];
					py1 = y2 + dir[i][1];
					if (px1 >= 0 && px1 < x && py1 < y && py1 >= 0 && visit1[px1][py1] == 0
							&& a[px1].charAt(py1) != '#') {
						queue1_push(px1 * y + py1);
						visit1[px1][py1] = visit1[x2][y2] + 1;
					}
				}
			}
			int min = 100000;
			for (int i = 0; i < x; i++) {                            //对Y,M到所有的的@的距离进行筛选   找到最短路径
				for (int j = 0; j < y; j++) {
					if (a[i].charAt(j) == '@' && visit[i][j] > 0 && visit1[i][j] > 0) {
						 		min = min > (visit[i][j] - 1 + visit1[i][j] - 1) ? (visit[i][j] - 1 + visit1[i][j] - 1) : min;
					}
				}
			}
			System.out.println(min * 11);       
		}
		s.close();
	}
	static void queue_push(int x) {
		queue[++top] = x;
	}
	static void queue1_push(int x) {
		queue1[++top1] = x;
	}
	static int queue_pop() {
		return queue[under++];
	}
	static int queue1_pop() {
		return queue1[under1++];
	}
}

  

原文地址:https://www.cnblogs.com/LIUWEI123/p/5676611.html