多源BFS
例題:173. 矩陣距離
多源bfs問題
將所有源點加入到隊列,求出所有多源起點到所有點的最短距離
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
static int N = 1010;
static int n;
static int m;
static char[][] g = new char[N][N];
static int[][] dist = new int[N][N];
static int[] dx = new int[]{-1, 0, 1, 0};
static int[] dy = new int[]{0, 1, 0, -1};
static void bfs() {
Queue<PIIs> q = new LinkedList<PIIs>();
for (int i = 0; i < n; i++) Arrays.fill(dist[i], -1);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
if (g[i][j] == '1') {
dist[i][j] = 0;
q.add(new PIIs(i, j));
}
}
while (!q.isEmpty()) {
PIIs t = q.poll();
for (int i = 0; i < 4; i++) {
int a = t.x + dx[i];
int b = t.y + dy[i];
if (a < 0 || a >= n || b < 0 || b >= m) continue;
if (dist[a][b] != -1) continue;
dist[a][b] = dist[t.x][t.y] + 1;
q.add(new PIIs(a, b));
}
}
}
public static void main(String[] args) throws IOException {
Scanner scan = new Scanner(System.in);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
n = scan.nextInt();
m = scan.nextInt();
for (int i = 0; i < n; i++) {
char[] charArray = scan.next().toCharArray();
for (int j = 0; j < m; j++) {
g[i][j] = charArray[j];
}
}
bfs();
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
out.write(dist[i][j] + " ");
}
out.write("\n");
}
out.flush();
}
}
class PIIs {
public int x;
public int y;
public PIIs(int x, int y) {
this.x = x;
this.y = y;
}
}
最小步數模型
例題:魔板
import java.util.*;
public class Main {
static char[][] g = new char[2][4];
static Map<String, Integer> dist = new HashMap<>();
static Map<String, Pair> pre = new HashMap<>();
static Queue<String> q = new LinkedList<>();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x;
String start = "", end = "";
for (int i = 0; i < 8; i++) {
x = sc.nextInt();
end += (char)(x + '0');
}
for (int i = 0; i < 8; i++) {
start += (char)(i + '1');
}
bfs(start, end);
System.out.println(dist.get(end));
StringBuilder res = new StringBuilder();
while (end != start) {
Pair p = pre.get(end);
if (p == null) continue;
res.append(p.c);
end = p.s;
}
res.reverse();
String realRes = res.toString();
if (realRes.length() > 0) System.out.println(realRes);
}
private static void bfs(String start, String end) {
if (start.equals(end)) return;
q.add(start);
dist.put(start, 0);
while (q.size() > 0) {
String t = q.poll();
String[] m = new String[3];
m[0] = move0(t);
m[1] = move1(t);
m[2] = move2(t);
for (int i = 0; i < 3; i++) {
String mm = m[i];
if (!dist.containsKey(mm)) {
dist.put(mm, dist.get(t) + 1);
pre.put(mm, new Pair((char)(i + 'A'), t));
if (mm.equals(end)) break;
q.add(mm);
}
}
}
}
private static String move0(String state) {
set(state);
for (int i = 0; i < 4; i++) {
swap(g, 0, i, 1, i);
}
return get();
}
private static void swap(char[][] g, int x1, int y1, int x2, int y2) {
char t = g[x1][y1];
g[x1][y1] = g[x2][y2];
g[x2][y2] = t;
}
private static String move1(String state) {
set(state);
char v0 = g[0][3], v1 = g[1][3];
for (int i = 3; i > 0; i--) {
for (int j = 0; j < 2; j++) {
g[j][i] = g[j][i - 1];
}
}
g[0][0] = v0;
g[1][0] = v1;
return get();
}
private static String move2(String state) {
set(state);
char v = g[0][1];
g[0][1] = g[1][1];
g[1][1] = g[1][2];
g[1][2] = g[0][2];
g[0][2] = v;
return get();
}
private static void set(String state) {
for (int i = 0; i < 4; i++) {
g[0][i] = state.charAt(i);
}
for (int i = 3, j = 4; i >= 0; i--, j++) {
g[1][i] = state.charAt(j);
}
}
private static String get() {
StringBuilder res = new StringBuilder();
for (int i = 0; i < 4; i++) {
res.append(g[0][i]);
}
for (int i = 3; i >= 0; i--) {
res.append(g[1][i]);
}
return res.toString();
}
}
class Pair{
char c;
String s;
public Pair(char c, String s) {
this.c = c;
this.s = s;
}
}
雙端隊列廣搜
例題:175. 電路維修
【WA了】
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
static int N = 510;
static int n;
static int m;
static char[][] g = new char[N][N];
static int[][] dist = new int[N][N];
static boolean[][] st = new boolean[N][N];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
while (T-- > 0) {
n = sc.nextInt();
m = sc.nextInt();
for (int i = 0; i < n; i++) {
g[i] = sc.next().toCharArray();
}
if ((n + m & 1) == 1) {
System.out.println("NO SOLUTION");
}else {
System.out.println(bfs());
}
}
}
private static int bfs() {
LinkedList<Pair> q = new LinkedList<>();
for (boolean[] x : st) Arrays.fill(x, false);
for (int[] x : dist) Arrays.fill(x, 0x3f);
char[] cs = "\\/\\/".toCharArray();//感覺問題出在這
int[] dx = {-1, -1, 1, 1};
int[] dy = {-1, 1, 1, -1};
int[] ix = {-1, -1, 0, 0};
int[] iy = {-1, 0, 0, -1};
dist[0][0] = 0;
q.add(new Pair(0, 0));
while (!q.isEmpty()) {
Pair t = q.poll();
int x = t.x, y = t.y;
if (x == n && y == m) return dist[x][y];
if (st[x][y]) continue;
st[x][y] = true;
for (int i = 0; i < 4; i++) {
int a = x + dx[i];
int b = y + dy[i];
if (a < 0 || a > n || b < 0 || b > m) continue;
int ga = x + ix[i];
int gb = y + iy[i];
int w = g[ga][gb] != cs[i] ? 1 : 0;
int d = dist[x][y] + w;
if (d <= dist[a][b]) {
dist[a][b] = d;
if (w == 0) {
q.addFirst(new Pair(a, b));//Queue沒有這個函數
}else {
q.add(new Pair(a, b));
}
}
}
}
return -1;//一定不會被執行到
}
}
class Pair{
int x;
int y;
public Pair(int x, int y) {
this.x = x;
this.y = y;
}
}