Adjacency Matrix
邻接矩阵法
邻接矩阵法用一个二维数组保存顶点之间是否有边、弧或权值。它的核心优点是判断两个顶点是否相邻很直接,核心代价是空间只和顶点数有关,即使边很少也要开 $|V|^2$ 个单元。
基本定义
设图 $G=(V,E)$ 有 $n$ 个顶点,将顶点编号为 $v_1,v_2,\cdots,v_n$。邻接矩阵 $A$ 是一个 $n\times n$ 的矩阵:
$$
A[i][j]=
\begin{cases}
1, & (v_i,v_j)\in E \text{ 或 } \langle v_i,v_j\rangle\in E\
0, & (v_i,v_j)\notin E \text{ 且 } \langle v_i,v_j\rangle\notin E
\end{cases}
$$
- 对无向图,$A[i][j]=1$ 表示 $v_i$ 与 $v_j$ 之间有边。
- 对有向图,$A[i][j]=1$ 表示存在从 $v_i$ 指向 $v_j$ 的弧。
- 顶点中可以保存更复杂的信息;矩阵单元可以用
bool、枚举型或整型表示边是否存在。
在普通 0/1 邻接矩阵中,0 只表示“没有边或弧”,它不是代价。
在带权图或最短路径算法使用的代价矩阵中,矩阵单元表示“从 $v_i$ 到 $v_j$ 的代价”。这时不相连的两个顶点不能写成 0,否则会被算法误认为存在一条零代价边,应写成 $\infty$;主对角线通常写成 0,表示顶点到自身的代价为 0。
无向图的邻接矩阵
无向边 $(v_i,v_j)$ 没有方向,所以矩阵中要同时记录两个位置:
$$
A[i][j]=1,\quad A[j][i]=1
$$
因此无向图的邻接矩阵一定关于主对角线对称。
在无向图中,第 $i$ 个顶点的度等于第 $i$ 行非零元素个数,也等于第 $i$ 列非零元素个数。
有向弧 $\langle v_i,v_j\rangle$ 只能说明从 $v_i$ 到 $v_j$ 有边,不能反推从 $v_j$ 到 $v_i$ 有边:
$$
A[i][j]=1 \not\Rightarrow A[j][i]=1
$$
- 第 $i$ 行非零元素个数:$v_i$ 的出度。
- 第 $i$ 列非零元素个数:$v_i$ 的入度。
- 第 $i$ 个顶点的度:第 $i$ 行非零元素个数 + 第 $i$ 列非零元素个数。
查找相邻边或弧
邻接矩阵适合快速判断两个指定顶点之间是否有边或弧:
1 | // Returns whether there is an edge or arc from `from` to `to`. |
但如果要列出某个顶点的全部邻接边,就要扫描矩阵:
- 无向图:扫描第 $i$ 行或第 $i$ 列,非零位置就是相邻顶点。
- 有向图找出边:扫描第 $i$ 行。
- 有向图找入边:扫描第 $i$ 列。
这些操作的时间复杂度都是 $O(|V|)$。
带权图的邻接矩阵
带权图也称网。带权图的矩阵单元不再只表示 0 或 1,而是保存边或弧的权值。
常用约定:
- 若 $v_i$ 到 $v_j$ 有边或弧,则
edge[i][j]保存权值。 - 若 $v_i$ 到 $v_j$ 没有边或弧,则
edge[i][j]记为 $\infty$。 - 主对角线常记为 $0$,表示顶点到自身的距离为 $0$;也有材料会把所有不存在的边统一记作 $\infty$,做题时按题目约定判断。
- C 语言里常用一个足够大的整数表示 $\infty$,例如
INT_MAX或自定义INF。
C 语言表示
1 |
|
对带权图,不能只用 edge[i][j] != 0 判断是否有边,因为 $0$ 可能是合法权值,也可能是主对角线。更稳妥的做法是把“无边”统一记为 INF,或者另设 bool hasEdge[][]。
邻接矩阵的空间复杂度为:
$$
O(|V|^2)
$$
它只和顶点数有关,和实际边数无关。因此:
- 适合存储稠密图。
- 不适合存储稀疏图,因为大量矩阵单元可能都表示“无边”。
- 判断两个顶点是否相邻是 $O(1)$。
- 查找一个顶点的全部邻接点需要 $O(|V|)$。
无向图邻接矩阵的压缩存储
无向图的邻接矩阵是对称矩阵,因此可以只存主对角线加下三角区,或只存主对角线加上三角区。这样可以把 $n\times n$ 个单元压缩为:
$$
\frac{n(n+1)}{2}
$$
若按行优先存储主对角线和下三角区,且矩阵下标从 $1$ 开始、一维数组下标从 $0$ 开始,则:
$$
k=\frac{i(i-1)}{2}+j-1,\quad i\ge j
$$
若遇到 $i<j$,利用对称性 $a_{i,j}=a_{j,i}$,转成:
$$
k=\frac{j(j-1)}{2}+i-1,\quad i<j
$$
1 | // Converts a symmetric matrix coordinate to a compressed-array index. |
矩阵幂与路径条数
设图 $G$ 的邻接矩阵为 $A$,且矩阵元素只表示 $0/1$。则:
$$
A^n[i][j]
$$
表示从顶点 $i$ 到顶点 $j$ 的长度为 $n$ 的路径条数。
这里的路径长度按边或弧的条数计算。例如 $A^2[i][j]$ 会枚举所有中间顶点 $k$:
$$
A^2[i][j]=\sum_{k=1}^{|V|}A[i][k]\cdot A[k][j]
$$
每一项 $A[i][k]\cdot A[k][j]$ 表示“能否从 $i$ 先到 $k$,再从 $k$ 到 $j$”。乘积为 $1$ 就代表存在一条经过 $k$ 的长度为 $2$ 的路径。
若 $A^2[2][2]=i$,表示从顶点 $2$ 出发,走两条边又回到顶点 $2$ 的路径有 i 条。