https://mp.weixin.qq.com/s?__biz=MzU4NDE3MTEyMA==&mid=2247488007&idx=1&sn=9d0dcfdf475168d26a5a4bd6fcd3505d&chksm=fd9cb918caeb300e1c8844583db5c5318a89e60d8d552747ff8c2256910d32acd9013c93058f&scene=178&cur_album_id=1986005834513940488#rd%201%20%E8%B8%A9%20%E5%9B%9E%E5%A4%8D%20%E5%88%86%E4%BA%AB%20%E4%B8%BE%E6%8A%A5

    首先学习三种存图方式
    约定 n 为点数,m 为边数

    1. 邻接表

    与数组存储单链表的实现一致(头插法)
    「稀疏图」:m≈n

    1. int[] he = new int[N], e = new int[M], ne = new int[M], w = new int[M];
    2. //idx表示当前边的下标
    3. int idx;
    4. //a节点指向b节点,权重为c
    5. void add(int a, int b, int c) {
    6. e[idx] = b; //e数组存储当前边指向的节点
    7. w[idx] = c; //w数组存储当前节点的权重
    8. ne[idx] = he[a]; //ne数组用于找到下一条边
    9. he[a] = idx; //he数组存储当前边所对应边的集合(链表)的头节点
    10. idx++;
    11. }
    12. //遍历所有由 a 点发出的边
    13. for (int i = he[a]; i != -1; i = ne[i]) {
    14. int b = e[i], c = w[i];
    15. }
    1. 邻接矩阵

    二维矩阵来进行存图
    「稠密图」: m≈n²

    1. // 邻接矩阵数组:w[a][b] = c 代表从 a 到 b 有权重为 c 的边
    2. int[][] w = new int[N][N];
    3. // 加边操作
    4. void add(int a, int b, int c) {
    5. w[a][b] = c;
    6. }