找回密码
 立即注册
首页 业界区 科技 算法day43-图论(1)

算法day43-图论(1)

巩芷琪 2025-6-17 21:09:10
目录


  • 理论基础
  • 深搜理论基础
  • 所有可达路径
  • 广搜理论基础
一、理论基础

1.  图的种类
  有向图、无向图、权值
2. 度
  度【无向图】:有多少条边
  出度、入度【有向图】:箭头指出去、箭头指回来
 3. 连通性
  连通图【无向图】:图里面任何一个节点可以到达其他所有节点
  强连通图:【有向图】:图里面任何一个节点可以到达其他所有节点
  连通分量【无向图】:极大连通子图,一个子图里面任何一个节点可以到达任何其他节点
  强连通分量【有向图】
4. 图的构造(很重要!!)
  朴素存储:二维数组,一一对应,把每条边两个节点记录下来
  邻接矩阵:二维数组,有相连的就标记为1(缺点是当节点数较多时,占用内存空间)
  邻接表:数组+链表(适合节点很多,边很少)
5. 图的遍历
  DFS、BFS
二、深搜理论基础

   深搜的概念、流程。
  深搜的伪代码。
三、所有可达路径

 98. 所有可达路径
1.png

 方法一:邻接矩阵存储
  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.Scanner;
  4. public class Main {
  5.     static List<List<Integer>> result = new ArrayList<>(); // 收集符合条件的路径
  6.     static List<Integer> path = new ArrayList<>(); // 1节点到终点的路径
  7.     public static void dfs(int[][] graph, int x, int n) {
  8.         // 当前遍历的节点x 到达节点n
  9.         if (x == n) { // 找到符合条件的一条路径
  10.             result.add(new ArrayList<>(path));
  11.             return;
  12.         }
  13.         for (int i = 1; i <= n; i++) { // 遍历节点x链接的所有节点
  14.             if (graph[x][i] == 1) { // 找到 x链接的节点
  15.                 path.add(i); // 遍历到的节点加入到路径中来
  16.                 dfs(graph, i, n); // 进入下一层递归
  17.                 path.remove(path.size() - 1); // 回溯,撤销本节点
  18.             }
  19.         }
  20.     }
  21.     public static void main(String[] args) {
  22.         Scanner scanner = new Scanner(System.in);
  23.         int n = scanner.nextInt();
  24.         int m = scanner.nextInt();
  25.         // 节点编号从1到n,所以申请 n+1 这么大的数组
  26.         int[][] graph = new int[n + 1][n + 1];
  27.         for (int i = 0; i < m; i++) {
  28.             int s = scanner.nextInt();
  29.             int t = scanner.nextInt();
  30.             // 使用邻接矩阵表示无向图,1 表示 s 与 t 是相连的
  31.             graph[s][t] = 1;
  32.         }
  33.         path.add(1); // 无论什么路径已经是从1节点出发
  34.         dfs(graph, 1, n); // 开始遍历
  35.         // 输出结果
  36.         if (result.isEmpty()) System.out.println(-1);
  37.         for (List<Integer> pa : result) {
  38.             for (int i = 0; i < pa.size() - 1; i++) {
  39.                 System.out.print(pa.get(i) + " ");
  40.             }
  41.             System.out.println(pa.get(pa.size() - 1));
  42.         }
  43.     }
  44. }
复制代码
四、广搜理论基础

1. 广搜的概念

广度优先搜索(Breadth-First Search,简称 BFS)是一种图的遍历算法,从起点开始,一层一层地向外扩展搜索,直到遍历完所有可以到达的节点。
它的本质是使用队列(Queue)来保证节点的访问顺序:先进先出,每次从队首取出一个节点,将它未访问的邻接节点加入队尾。
BFS 常用于:

  • 求最短路径(单位边权情况下)
  • 判断连通性、层次结构
  • 拓扑排序等问题

2. 广搜的特点


  • 按“距离起点的远近”逐层扩展
  • 通常需要配合一个 visited[] 数组,防止重复访问
  • 对于无权图最短路径问题非常高效
  • 可用于搜索所有从起点出发的最短可达路径

3. BFS 的伪代码框架
  1. import java.util.ArrayList;
  2. import java.util.LinkedList;
  3. import java.util.List;
  4. import java.util.Scanner;
  5. public class Main {
  6.     static List<List<Integer>> result = new ArrayList<>(); // 收集符合条件的路径
  7.     static List<Integer> path = new ArrayList<>(); // 1节点到终点的路径
  8.     public static void dfs(List<LinkedList<Integer>> graph, int x, int n) {
  9.         if (x == n) { // 找到符合条件的一条路径
  10.             result.add(new ArrayList<>(path));
  11.             return;
  12.         }
  13.         for (int i : graph.get(x)) { // 找到 x指向的节点
  14.             path.add(i); // 遍历到的节点加入到路径中来
  15.             dfs(graph, i, n); // 进入下一层递归
  16.             path.remove(path.size() - 1); // 回溯,撤销本节点
  17.         }
  18.     }
  19.     public static void main(String[] args) {
  20.         Scanner scanner = new Scanner(System.in);
  21.         int n = scanner.nextInt();
  22.         int m = scanner.nextInt();
  23.         // 节点编号从1到n,所以申请 n+1 这么大的数组
  24.         List<LinkedList<Integer>> graph = new ArrayList<>(n + 1);
  25.         for (int i = 0; i <= n; i++) {
  26.             graph.add(new LinkedList<>());
  27.         }
  28.         while (m-- > 0) {
  29.             int s = scanner.nextInt();
  30.             int t = scanner.nextInt();
  31.             // 使用邻接表表示 s -> t 是相连的
  32.             graph.get(s).add(t);
  33.         }
  34.         path.add(1); // 无论什么路径已经是从1节点出发
  35.         dfs(graph, 1, n); // 开始遍历
  36.         // 输出结果
  37.         if (result.isEmpty()) System.out.println(-1);
  38.         for (List<Integer> pa : result) {
  39.             for (int i = 0; i < pa.size() - 1; i++) {
  40.                 System.out.print(pa.get(i) + " ");
  41.             }
  42.             System.out.println(pa.get(pa.size() - 1));
  43.         }
  44.     }
  45. }
复制代码
4. Java 中 BFS 的实现要点


  • 使用 Queue 作为主队列结构(推荐 LinkedList 实现)
  • 图的存储结构通常使用邻接表 List 或邻接矩阵 int[][]
  • 搭配一个布尔数组 visited[] 或整数数组 dist[] 来记录访问状态或层数
 

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册