本质上是用链表实现的邻接表。
以每个节点
为表头创建链表
每个链表的第一位为当个节点
往后的元素
都是该节点
的出度或者入度,也可以通过建立一个逆邻接表
来同时存储二者。
下文为OIwiki的核心实现代码
1 2 3 4 5 6 7 8 9 10 11
| void add(int u, int v) { nxt[++cnt] = head[u]; head[u] = cnt; to[cnt] = v; }
for (int i = head[u]; ~i; i = nxt[i]) { int v = to[i]; }
|
`
以及完整实现代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #include <iostream> #include <vector>
using namespace std;
int n, m; vector<bool> vis; vector<int> head, nxt, to;
void add(int u, int v) { nxt.push_back(head[u]); head[u] = to.size(); to.push_back(v); }
bool find_edge(int u, int v) { for (int i = head[u]; ~i; i = nxt[i]) { if (to[i] == v) { return true; } } return false; }
void dfs(int u) { if (vis[u]) return; vis[u] = true; for (int i = head[u]; ~i; i = nxt[i]) dfs(to[i]); }
int main() { cin >> n >> m;
vis.resize(n + 1, false); head.resize(n + 1, -1);
for (int i = 1; i <= m; ++i) { int u, v; cin >> u >> v; add(u, v); }
return 0; }
|
但是笔者更加习惯于使用结构体
如下构造结构体
1 2 3 4 5 6 7 8
| struct Edge { int to, w, next; }edge[maxn];
int head[maxn];
|
初始化部分略过
添加边代码如下
1 2 3 4 5 6 7
| void add(int u, int v,int w) { edge[cnt].to = v; edge[cnt].w = w; edge[cnt].next = head[u]; head[u] = cnt ++; }
|
查询节点出度代码如下
1 2 3 4 5 6 7
| void Find(int u) { for(int i = head[u]; i~; i = edge[i].next) { cout << edge[i].to << " " << edge[i].w; } }
|
非常煎蛋实用存储图