bfs解决最短的问题,那个点到哪个点要走的最短的距离,bfs一定要写vis数组,访问过的节点要标注为1,走下一步(也就是往queue中放新节点时)一定要判断vis【】等于0,即没有访问过。
dfs呢?dfs解决分成几块,哪两个点之间是否能联通的情况。也一定要有vis数组其他过程与上述一样,但是如有回溯的需要的话,就需要在回溯时再把vis改成0
树与图的关系
1、没有圈的连通图,就是树(连通图:任意两点相连,强连通图:有向图任意两点相连)
2、没有圈的非联通图,就是森林
3、一棵树边数等于顶点数-1
4、边数等于顶点数-1的连通图就是树
有向图的术语:
没有圈的有向图叫做有向无环图,(DAG directed acyclic graph)
邻接表的表示:
package org.lanqiao.algo.elementary._12_graph;
import java.util.ArrayList;
import java.util.List;
/*邻接表*/
public class GraphNode_AL {
public int val; //每一个顶点的意思
private List<GraphNode_AL> neighbors;//邻居
public boolean checked = false;
public GraphNode_AL(int val) { //构造器
this.val = val;
}
public GraphNode_AL getNeighbor(int i) { //访问器,给他一个邻居的编号,返回邻居
return neighbors.get(i);
}
public void add(GraphNode_AL node) { //更改器,传一个邻居进来
if (this.neighbors == null) this.neighbors = new ArrayList<>();
this.neighbors.add(node);
}
public int size() {
return this.neighbors.size();
}
}
package org.lanqiao.algo.elementary._12_graph.dfs;
import org.lanqiao.algo.elementary._12_graph.GraphNode_AL;
/*邻接表来表示图*/
public class Graph {
public static void main(String[] args) {
GraphNode_AL n1 = new GraphNode_AL(1);
GraphNode_AL n2 = new GraphNode_AL(2);
GraphNode_AL n3 = new GraphNode_AL(3);
GraphNode_AL n4 = new GraphNode_AL(4);
GraphNode_AL n5 = new GraphNode_AL(5);
GraphNode_AL n6 = new GraphNode_AL(6);
GraphNode_AL n7 = new GraphNode_AL(7);
GraphNode_AL n8 = new GraphNode_AL(8);
GraphNode_AL n9 = new GraphNode_AL(9);
n1.add(n2);
n1.add(n3);
n1.add(n7);
n1.add(n8);
n1.add(n9);
n2.add(n1);
n2.add(n5);
n3.add(n1);
n3.add(n5);
n3.add(n6);
n4.add(n1);
n4.add(n6);
n5.add(n2);
n5.add(n3);
n6.add(n3);
n6.add(n4);
n7.add(n1);
n8.add(n1);
n9.add(n1);
dfs(n9);
}
static void dfs(GraphNode_AL node) {
System.out.println(node.val);
node.checked = true;
for (int i = 0; i < node.size(); i++) {
GraphNode_AL graphNode = node.getNeighbor(i);
if (graphNode.checked == false)
dfs(graphNode);
}
}
}
边集的表示
package org.lanqiao.algo.elementary._12_graph;
/**
* 边 的封装
* 边集可以用来表示图
*/
public class Edge<T> implements Comparable<Edge> {
private T start;
private T end;
private int distance;
public Edge(T start, T end, int distance) {
this.start = start;
this.end = end;
this.distance = distance;
}
public T getStart() {
return start;
}
public void setStart(T start) {
this.start = start;
}
public T getEnd() {
return end;
}
public void setEnd(T end) {
this.end = end;
}
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
this.distance = distance;
}
@Override
public String toString() {
return start + "->" + end + ":" + distance;
}
@Override
public int compareTo(Edge obj) {
int targetDis = obj.getDistance();
return distance > targetDis ? 1 : (distance == targetDis ? 0 : -1);
}
}
package org.lanqiao.algo.elementary._12_graph;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MapBuilder {
public List<Edge> build() {
List<Edge> edges = new ArrayList<>();
edges.add(new Edge("1", "2", 4));
edges.add(new Edge("1", "3", -1));
edges.add(new Edge("2", "3", 3));
edges.add(new Edge("2", "4", 5));
edges.add(new Edge("4", "5", 10));
// Collections.sort(edges);
return edges;
}
public int getPointNum() {
return 5;
}
public List<Edge> build1() {
List<Edge> edges = new ArrayList<>();
edges.add(new Edge("1", "2", 4));
edges.add(new Edge("1", "3", -1));
edges.add(new Edge("2", "3", 3));
edges.add(new Edge("2", "4", 5));
edges.add(new Edge("4", "5", 10));
edges.add(new Edge("0", "2", 10));
edges.add(new Edge("0", "3", 10));
edges.add(new Edge("0", "4", 1));
edges.add(new Edge("0", "5", 1));
Collections.sort(edges);
return edges;
}
public int getPointNum1() {
return 6;
}
}
2、图的dfs
/*给定一个方阵,定义连通:上下左右相邻,并且值相同。
可以想象成一张地图,不同的区域被涂以不同颜色。
输入:
整数N, (N<50)表示矩阵的行列数
接下来N行,每行N个字符,代表方阵中的元素
接下来一个整数M,(M<1000)表示询问数
接下来M行,每行代表一个询问,
格式为4个整数,y1,x1,y2,x2,
表示询问(第y1行,第x1列) 与 (第y2行,第x2列) 是否连通。
连通输出true,否则false
例如:
10
0010000000
0011100000
0000111110
0001100010
1111010010
0000010010
0000010011
0111111000
0000010000
0000000000
3
0 0 9 9
0 2 6 8
4 4 4 6
程序应该输出:
false
true
true*/
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
char[][] graph = new char[N][N];
for(int i=0;i<N;i++){
graph[i] = sc.nextLine().toCharArray();
}
int M =sc.nextInt();
int[][] query = new int[M][4];
for (int i = 0; i < M; i++) {
for (int j = 0; j < 4; j++) {
query[i][j] = sc.nextInt();
}
}
// M个起点和终点
for (int i = 0; i < M; i++) {
//对每个起点和终点,检查是否连通
boolean ok_fal = check(graph, new int[N][N], query[i]);//一个例子一个例子查
System.out.println(ok_fal);
}
}
static boolean check(char[][] graph, int[][] label, int[] points){
int x1 = points[0];
int y1 = points[1];
int x2 = points[2];
int y2 = points[3];
if(x1 ==x2 && y1 ==y2){
return true;
}
int value = graph[x1][y1];
boolean f1 = false;
boolean f2 = false;
boolean f3 = false;
boolean f4 = false;
//往左走
if(x1-1>=0 && label[x1-1][y1]==0 &&graph[x1 - 1][y1] == value){
label[x1 - 1][y1] = 1; // 坐标的位置标记为已访问
points[0] = x1 - 1; // 把左边的点作为新起点,递归
f1 = check(graph, label, points);
//回溯
label[x1 - 1][y1] = 0;
points[0] = x1;
}
//往右走
if (x1 + 1 < graph.length && label[x1 + 1][y1] == 0 && graph[x1 + 1][y1] == value) {
label[x1 + 1][y1] = 1;
points[0] = x1 + 1;
f2 = check(graph, label, points);
label[x1 + 1][y1] = 0;
points[0] = x1;
}
//往上走
if (y1 - 1 >= 0 && label[x1][y1 - 1] == 0 && graph[x1][y1 - 1] == value) {
label[x1][y1 - 1] = 1;
points[1] = y1 - 1;
f3 = check(graph, label, points);
label[x1][y1 - 1] = 0;
points[1] = y1;
}
//往下走
if (y1 + 1 < graph.length && label[x1][y1 + 1] == 0 && graph[x1][y1 + 1] == value) {
label[x1][y1 + 1] = 1;
points[1] = y1 + 1;
f4 = check(graph, label, points);
label[x1][y1 + 1] = 0;
points[1] = y1;
}
return f1|| f2 || f3 || f4;
//若有一个可以,那就可行
}
}
2、/**
* 输入一个m行n列的字符矩阵,统计字符“@”组成多少个八连块。
* 如果两个字符“@”所在的格子相邻(横、竖或者对角线方向),就说它们属于同一个八连块。
*
* 分析:图的dfs
*/
public class Main{
static char[][] data = {
"*@@*@".toCharArray(),
"**@*@".toCharArray(),
"****@".toCharArray(),
"@@@*@".toCharArray(),
"@@**@".toCharArray(),
};
static int cnt;
static void dfs(int r,int c){
if(r<0 || r>=data.length || c<0 ||c>=data.length) return; //超出范围
if( data[r][c] == '*'){
return;
}
data[r][c] ='*';
dfs(r+1,c);
dfs(r-1,c);
dfs(r, c + 1);
dfs(r, c - 1);
dfs(r + 1, c + 1);
dfs(r + 1, c - 1);
dfs(r - 1, c - 1);
dfs(r - 1, c + 1);
}
public static void main(String[] args) {
for(int i=0;i<data.length;i++){
for(int j=0;j<data[0].length;j++){
if(dat