邻接表的构建(java)

112 阅读3分钟

如果题目的空间限制为512MB可以不必考虑这种 优化,直接使用arraylist[]存储邻接表,,但是空间限制很小的情况下,二维存储肯定是会mle的,那么我们可以用多个一维表来存储邻接表

原理

每一条有向边我们都会用cnt来记录是标号

这里我们会创建几个表:

1.head[i]: 用于表示节点i的第一条邻接边

2.next[i]: 表示第i条边之后是哪条边邻接

3.to[i]: 表示第i条边的终点是哪个节点

4.w[i]: 表示第i条边的权重是多少

看到这里可能会觉得很抽象,不急我们先屡屡关系

首先邻接表要看是哪个节点的邻接表,假设 是a节点的,那么a节点的第一条邻接边则是 第head[a]条边(假设值为b)

那么我们要去next中找到第二条邻接边也就是next[b],直到next[b]=0;

而to和w就按照正常情况去记录第cnt条边的终点和权重 ;

举例:

这个图包含以下边:

  1. 边 (1, 2)
  2. 边 (1, 3)
  3. 边 (2, 4)
  4. 边 (3, 4)
  5. 边 (3, 5)
  6. 边 (4, 5)

添加边的过程

  1. 添加边 (1, 2)
    • head[1] = 1,表示节点 1 的邻接表从边 1 开始。
    • next[1] = 0,表示边 1 是节点 1 的唯一邻接边。
    • to[1] = 2,表示边 1 的目标节点是 2。
  1. 添加边 (1, 3)
    • head[1] = 2,现在节点 1 的邻接表头指向边 2(新的边)。
    • next[2] = 1,表示边 2 的“下一条边”是边 1。
    • to[2] = 3,表示边 2 的目标节点是 3。
  1. 添加边 (2, 4)
    • head[2] = 3,表示节点 2 的邻接表从边 3 开始。
    • next[3] = 0,表示边 3 是节点 2 的唯一邻接边。
    • to[3] = 4,表示边 3 的目标节点是 4。
  1. 添加边 (3, 4)
    • head[3] = 4,表示节点 3 的邻接表从边 4 开始。
    • next[4] = 0,表示边 4 是节点 3 的唯一邻接边。
    • to[4] = 4,表示边 4 的目标节点是 4。
  1. 添加边 (3, 5)
    • head[3] = 5,表示节点 3 的邻接表从边 5 开始。
    • next[5] = 4,表示边 5 的“下一条边”是边 4。
    • to[5] = 5,表示边 5 的目标节点是 5。
  1. 添加边 (4, 5)
    • head[4] = 6,表示节点 4 的邻接表从边 6 开始。
    • next[6] = 0,表示边 6 是节点 4 的唯一邻接边。
    • to[6] = 5,表示边 6 的目标节点是 5。

代码实现:

  public static int n, m, s, cnt;

    // 最大节点数和最大边数,确保足够容纳图的所有数据
    public static int MAXN = 100001;
    public static int MAXM = 200001;

    // 存储图的信息
    public static int[] head = new int[MAXN]; // 存储每个节点的邻接表头
    public static int[] next = new int[MAXM]; // 存储图中每条边的下一个边
    public static int[] to = new int[MAXM];   // 存储边的目标节点
    public static int[] quan = new int[MAXM];  // 存储每条边的权重

添加:

// 添加一条边到图中
    cnt=1
    public static void add(int h, int t, int w) {
        next[cnt] = head[h]; // 将原来 h 的邻接表头指向当前边
        to[cnt] = t;         // 目标节点是 t
        quan[cnt] = w;       // 边的权重是 w
        head[h] = cnt++;     // 更新节点 h 的邻接表头为当前边,并递增边的计数器
    }

查找:

// 遍历与当前节点 h 相邻的所有节点
            for (int nex = head[h]; nex != 0; nex = next[nex]) {
                int nextNode = to[nex];  // 邻接节点
                int weight = quan[nex];  // 边的权重
            }