Day44 | 图论理论基础 98. 所有可达路径

语言

Java

图论理论基础

整体上一般分为 有向图 和 无向图

有向图就是有箭头的,无向图就是没有方向的。

有几条连线就是有几个度。

在有向图中,每个节点有出度和入度。

出度:从该节点出发的边的个数。

入度:指向该节点边的个数。

在无向图中,任何两个节点都是可以到达的,我们称之为连通图。

在有向图中,任何两个节点是可以相互到达的,我们称之为 强连通图。

98. 所有可达路径

98. 所有可达路径

题目

给定一个有 n 个节点的有向无环图,节点编号从 1 到 n。请编写一个函数,找出并返回所有从节点 1 到节点 n 的路径。每条路径应以节点编号的列表形式表示。

输入描述

第一行包含两个整数 N,M,表示图中拥有 N 个节点,M 条边

后续 M 行,每行包含两个整数 s 和 t,表示图中的 s 节点与 t 节点中有一条路径

输出描述

输出所有的可达路径,路径中所有节点之间空格隔开,每条路径独占一行,存在多条路径,路径输出的顺序可任意。如果不存在任何一条路径,则输出 -1。

注意输出的序列中,最后一个节点后面没有空格! 例如正确的答案是 `1 3 5`,而不是 `1 3 5 `, 5后面没有空格!

思路

本题是深度优先遍历的方式去做的。

我们用深搜三部曲来分析题目:

1.确认递归函数,参数

首先我们dfs函数一定要存一个图,用来遍历的,需要存一个目前我们遍历的节点,定义为x。

还需要存一个n,表示终点,我们遍历的时候,用来判断当 x==n 时候 标明找到了终点。

2.确认终止条件

当遍历到n的时候就相当于找到一条路径

3.处理目前搜索节点出发的路径

接下来是走 当前遍历节点x的下一个节点。

4.最后打印结果

代码

java 复制代码
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    static List<List<Integer>> result = new ArrayList<>(); // 收集符合条件的路径
    static List<Integer> path = new ArrayList<>(); // 1节点到终点的路径

    public static void dfs(int[][] graph, int x, int n) {
        // 当前遍历的节点x 到达节点n
        if (x == n) { // 找到符合条件的一条路径
            result.add(new ArrayList<>(path));
            return;
        }
        for (int i = 1; i <= n; i++) { // 遍历节点x链接的所有节点
            if (graph[x][i] == 1) { // 找到 x链接的节点
                path.add(i); // 遍历到的节点加入到路径中来
                dfs(graph, i, n); // 进入下一层递归
                path.remove(path.size() - 1); // 回溯,撤销本节点
            }
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();

        // 节点编号从1到n,所以申请 n+1 这么大的数组
        int[][] graph = new int[n + 1][n + 1];

        for (int i = 0; i < m; i++) {
            int s = scanner.nextInt();
            int t = scanner.nextInt();
            // 使用邻接矩阵表示无向图,1 表示 s 与 t 是相连的
            graph[s][t] = 1;
        }

        path.add(1); // 无论什么路径已经是从1节点出发
        dfs(graph, 1, n); // 开始遍历

        // 输出结果
        if (result.isEmpty()) System.out.println(-1);
        for (List<Integer> pa : result) {
            for (int i = 0; i < pa.size() - 1; i++) {
                System.out.print(pa.get(i) + " ");
            }
            System.out.println(pa.get(pa.size() - 1));
        }
    }
}

易错点

打印结果的时候最后不要留有空格。

总结

今天开始图论了,但是感觉还是有点不理解,等明天做题再看看。

继续加油!

毅力是永久的享受

相关推荐
2601_9516437718 分钟前
Python第一,Java跌出前三,C语言杀回来了
java·c语言·python·编程语言排行·技术趋势
IT 行者2 小时前
GitHub Spec Kit 实战(五):/speckit.tasks 怎么拆——Spec Kit 五部曲收官
java·ai编程·claude
(Charon)3 小时前
【C++ 面试高频基础:指针、引用、const、static、new/delete 总结】
java·开发语言
一只齐刘海的猫3 小时前
【Leetcode】找到字符串中所有字母异位词
算法·leetcode·职场和发展
Yeats_Liao3 小时前
Feed流系统设计(三):数据模型与存储设计,从表结构到Redis收件箱
java·javascript·redis
JiaHao汤3 小时前
分布式事务方案全景:从理论到 Seata 落地
java·分布式·spring·spring cloud
海清河晏1113 小时前
数据结构 | 八大排序
数据结构·算法·排序算法
liulilittle4 小时前
固定数组时间轮的槽过载优化:桶链表与批次执行
网络·数据结构·链表
色空大师4 小时前
【debug调试详解-idea】
java·ide·intellij-idea·调试·远程调试
程序猿阿越4 小时前
AutoMQ源码(一)读、写、Compaction
java·后端·源码