图的存储

834 字
4 分钟
图的存储

图的存储#

图论题的第一步通常不是跑算法,而是先把图存起来。

不同存储方式适合不同场景。常见方式有:

  • 邻接矩阵
  • 边集数组
  • 邻接表
  • 链式前向星

1、先理解图里的基本元素#

图由点和边组成。

如果有一条边:

a -> b,权重为 c

那么存图时至少要记录:

起点 a
终点 b
权重 c

如果是无向图,一条边 a - b 通常要存两次:

a -> b
b -> a

2、邻接矩阵#

邻接矩阵用二维数组存边:

int g[N][N];

如果 g[a][b] = c,表示从 a 到 b 有一条权重为 c 的边。

初始化时一般写:

memset(g, 0x3f, sizeof g);
for (int i = 1; i <= n; i++) g[i][i] = 0;

加边:

g[a][b] = min(g[a][b], c);

邻接矩阵的优点是查询两点之间是否有边很快,O(1)。

缺点是空间复杂度是 O(n^2),点数大时开不下。

3、边集数组#

边集数组就是把每条边直接存成一个结构体:

struct Edge {
int a, b, w;
};
vector<Edge> edges;

加边:

edges.push_back({a, b, w});

这种写法适合 Kruskal 最小生成树,因为 Kruskal 需要把所有边拿出来排序。

4、vector 邻接表#

如果要经常遍历某个点的所有出边,可以用邻接表:

vector<pair<int, int>> g[N];

其中:

g[a] 存从 a 出发的所有边
pair 的 first 是终点,second 是权重

加边:

g[a].push_back({b, c});

遍历:

for (auto item : g[a]) {
int b = item.first;
int c = item.second;
}

这种写法直观,适合学习和一般题目。

5、链式前向星#

竞赛模板里经常使用链式前向星,本质上是用数组模拟邻接表。

const int N = 100010;
const int M = 200010;
int h[N], e[M], w[M], ne[M], idx;

含义:

h[a]:点 a 的第一条边编号
e[i]:第 i 条边的终点
w[i]:第 i 条边的权重
ne[i]:与第 i 条边同起点的下一条边编号
idx:当前边编号

初始化:

memset(h, -1, sizeof h);

加边:

void add(int a, int b, int c) {
e[idx] = b;
w[idx] = c;
ne[idx] = h[a];
h[a] = idx++;
}

遍历点 a 的所有出边:

for (int i = h[a]; i != -1; i = ne[i]) {
int b = e[i];
int c = w[i];
}

6、完整链式前向星模板#

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
const int M = 200010;
int n, m;
int h[N], e[M], w[M], ne[M], idx;
void add(int a, int b, int c) {
e[idx] = b;
w[idx] = c;
ne[idx] = h[a];
h[a] = idx++;
}
int main() {
cin >> n >> m;
memset(h, -1, sizeof h);
while (m--) {
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
}
for (int a = 1; a <= n; a++) {
cout << a << ":";
for (int i = h[a]; i != -1; i = ne[i]) {
cout << " -> " << e[i] << "(" << w[i] << ")";
}
cout << endl;
}
return 0;
}

7、怎么选择存图方式#

点数小、要快速查边:邻接矩阵
要给所有边排序:边集数组
要遍历每个点的出边:邻接表
追求数组模板和性能:链式前向星

8、原图笔记#

下面保留原来的图示,方便对照复习。

邻接矩阵#

边集数组#

邻接表#

链式邻接表#

链式前向星#

总结#

图的存储方式会影响后面算法的写法。学习 Dijkstra、Prim、拓扑排序这类算法时,建议优先掌握链式前向星,因为它和竞赛模板结合得最紧。

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

图的存储
https://blog.tjcheng.cn/posts/migrated/old-89/
作者
TengJinCheng
发布于
2025-11-29
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
TengJinCheng
Hello, I'm Teng.
公告
欢迎来到TengJinCheng工作铺!
音乐
封面

音乐

暂未播放

0:000:00
暂无歌词
分类
标签
站点统计
文章
157
分类
7
标签
114
总字数
109,939
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.13.4
文章许可
CC BY-NC-SA 4.0

文章目录