Graph Storage
In OI, to perform operations on graphs, one must first learn how to store graphs.
Convention
This article assumes the reader has already read and understood the basic content in Graph Theory Related Concepts. If difficulties are encountered while reading, one may also refer to Graph Theory Related Concepts.
In this article, \(n\) denotes the number of vertices in the graph, \(m\) denotes the number of edges, and \(d^+(u)\) denotes the out-degree of vertex \(u\), i.e., the number of edges starting from \(u\).
Direct Edge Storage
Method
Use an array to store edges, where each element in the array contains the start and end points of an edge (for weighted graphs, the edge weight is also included). (Alternatively, use multiple arrays to store the start points, end points, and edge weights separately.)
Reference Code
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 | |
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 | |
Complexity
Query whether a specific edge exists: \(O(m)\).
Traverse all outgoing edges of a vertex: \(O(m)\).
Traverse the entire graph: \(O(nm)\).
Space complexity: \(O(m)\).
Application
Due to the low efficiency of traversal with direct edge storage, it is generally not used for graph traversal.
In Kruskal's algorithm, since edges need to be sorted by weight, direct edge storage is required.
In some problems, multiple graphs need to be constructed (e.g., constructing the original graph and its reverse graph). In such cases, one can either use multiple other data structures to store multiple graphs simultaneously or store the edges directly and reconstruct the graph using the stored edges when needed.
Adjacency Matrix
Method
Use a two-dimensional array adj to store edges, where adj[u][v] is 1 if there is an edge from \(u\) to \(v\), and 0 otherwise. For weighted graphs, adj[u][v] can store the weight of the edge from \(u\) to \(v\).
Reference Code
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 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Complexity
Query whether a specific edge exists: \(O(1)\).
Traverse all outgoing edges of a vertex: \(O(n)\).
Traverse the entire graph: \(O(n^2)\).
Space complexity: \(O(n^2)\).
Application
Adjacency matrices are only suitable for graphs without multiple edges (or where multiple edges can be ignored).
Their most significant advantage is the ability to query whether an edge exists in \(O(1)\).
Since adjacency matrices are inefficient on sparse graphs (especially on graphs with many vertices, where space becomes unmanageable), they are generally used only on dense graphs.
Adjacency List
Method
Use an array of data structures that support dynamic element addition, such as vector<int> adj[n + 1], to store edges. Here, adj[u] stores all relevant information (destination, edge weight, etc.) about the outgoing edges of vertex \(u\).
Reference Code
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 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
Complexity
Query whether an edge from \(u\) to \(v\) exists: \(O(d^+(u))\) (if sorted in advance, binary search can achieve \(O(\log(d^+(u)))\)).
Traverse all outgoing edges of vertex \(u\): \(O(d^+(u))\).
Traverse the entire graph: \(O(n+m)\).
Space complexity: \(O(m)\).
Application
Suitable for storing various types of graphs, unless there are special requirements (e.g., needing to quickly query whether an edge exists with a small number of vertices, in which case an adjacency matrix can be used).
Particularly suitable for scenarios where the outgoing edges of a vertex need to be sorted.
Linked Forward Star
Method
Essentially, it is an adjacency list implemented using linked lists. The core code is as follows:
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Reference Code
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 | |
Complexity
Query whether an edge from \(u\) to \(v\) exists: \(O(d^+(u))\).
Traverse all outgoing edges of vertex \(u\): \(O(d^+(u))\).
Traverse the entire graph: \(O(n+m)\).
Space complexity: \(O(m)\).
Application
Suitable for storing various types of graphs, but cannot quickly query whether an edge exists or conveniently sort the outgoing edges of a vertex.
The advantage is that edges are numbered, which can be very useful in some cases. Moreover, if the initial value of cnt is odd, i ^ 1 is the reverse edge of i when storing bidirectional edges (commonly used in network flow).
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用