深度/广度优先搜索

71 阅读2分钟

还是借助上一篇文章中亲子游戏的例子说明一下深度优先搜索示例:

import java.util.*;  
  
public class CandyGameDfs {  
// <p> 宝宝和妈妈参加亲子游戏,在一个二维矩阵(N*N)的格子地图上,宝宝和妈妈抽签决定各自的位置,地图上每个格子有不同的糖果数量,部分格子有障碍物。 </p> <p>  
// 游戏规则是妈妈必须在最短的时间(每个单位时间只能走一步)到达宝宝的位置,路上的所有糖果都可以拿走,不能走障碍物的格子,只能上下左右走。 </p> <div>  
// 请问妈妈在最短到达宝宝位置的时间内最多拿到多少糖果(优先考虑最短时间到达的情况下尽可能多拿糖果)。 </div>  
// -3:妈妈  
// -2:宝宝  
// -1:障碍  
// ≥0:糖果数(0表示没有糖果,但是可以走)  
// 4  
// 3 2 1 -3  
// 1 -1 1 1  
// 1 1 -1 2  
// -2 1 2 3  
  
static int mi = 0,mj = 0,si = 0,sj = 0;  
static Queue<Pos> queue = null; //记录已访问节点  
static boolean[][] visited = null; //标记是否已访问  
static List<Pos> posList = null; //记录所有的路线  
static int[][] arr;  
static Pos end;  
static boolean fined;  
public static void main(String[] args) {  
Scanner scanner = new Scanner(System.in);  
final int n = scanner.nextInt();  
arr = new int[n][n];  
  
for(int i = 0; i < n; i++){  
for(int j = 0; j < n; j++){  
arr[i][j] = scanner.nextInt();  
if(arr[i][j] == -3){  
mi = i;  
mj = j;  
}else if(arr[i][j] == -2){  
si = i;  
sj = j;  
}  
}  
}  
queue = new LinkedList<>(); //记录已访问节点  
visited = new boolean[n][n];  
posList = new LinkedList<>(); //记录所有的路线  
Pos start = new Pos(mi,mj,0); //开始位置  
end = new Pos(si,sj,0);  
dfsMs(start); //深度优先搜索  
  
System.out.println(posList.size());  
for(Pos pos : posList){  
int size = 0;  
int sum = 0;  
while (pos != null){  
System.out.println(pos.x + " " + pos.y + " "+ pos.count);  
pos = pos.pre;  
if(pos != null && pos.count > 0){  
sum+=pos.count;  
size++;  
}  
}  
System.out.println(size + 1 + " "+ sum);  
System.out.println("===");  
}  
  
}  
  
//这个还是深度搜索,deap first search,访问的方向对结果是有影响的。  
public static void dfsMs(Pos start){  
if(start.equals(end)){ //找到了  
posList.add(start);  
fined = true;  
return;  
}  
  
visited[start.x][start.y] = true; //已访问  
  
//向上  
if(start.x > 0 && !visited[start.x - 1][start.y] && arr[start.x - 1][start.y] != -1 && !fined){  
Pos tmp = new Pos(start.x-1,start.y,arr[start.x-1][start.y]);  
tmp.pre = start;  
dfsMs(tmp);  
}  
  
//向下  
if(start.x < arr.length-1 && !visited[start.x + 1][start.y] && arr[start.x + 1][start.y] != -1 && !fined){  
Pos tmp = new Pos(start.x+1,start.y,arr[start.x+1][start.y]);  
tmp.pre = start;  
dfsMs(tmp);  
}  
  
//向左  
if(start.y > 0 && !visited[start.x][start.y - 1] && arr[start.x][start.y-1] != -1 && !fined){  
Pos tmp = new Pos(start.x,start.y - 1,arr[start.x][start.y-1]);  
tmp.pre = start;  
dfsMs(tmp);  
}  
  
//向右  
if(start.y < arr.length - 1 && !visited[start.x][start.y+1] && arr[start.x][start.y+1] != -1 && !fined){  
Pos tmp = new Pos(start.x,start.y+1,arr[start.x][start.y+1]);  
tmp.pre = start;  
dfsMs(tmp);  
}  
//回溯  
if(start.pre != null && !fined){  
visited[start.pre.x][start.pre.y] = false;  
dfsMs(start.pre);  
}  
}  
  
static class Pos{  
int x;  
int y;  
int count;  
Pos pre;  
public Pos(int x,int y,int count){  
this.x = x;  
this.y = y;  
this.count = count;  
}  
  
  
@Override  
public boolean equals(Object o) {  
if (this == o) return true;  
if (o == null || getClass() != o.getClass()) return false;  
Pos pos = (Pos) o;  
return x == pos.x && y == pos.y;  
}  
  
@Override  
public int hashCode() {  
return Objects.hash(x, y);  
}  
}  
}