คู่มือโอลิมปิกคอมพิวเตอร์

Computer Olympiad Guide for Thai High School Students

Graph Structure

คำอธิบาย

  • กราฟเป็นโครงสร้างข้อมูลไม่เชิงเส้น ประกอบด้วย node (vertex) และ edge

  • มีนิยามดังนี้

    > A Graph consists of a finite set of vertices (or nodes) and set of Edges which connect a pair of nodes

Example

Undirected graph. Original diagram for this guide.

  • ในกราฟด้านบนประกอบด้วย set of vertices V = \left\{ 0,1,2,3,4 \right\} และ set of edges E = \left\{ 01,12,23,34,04,14,13 \right\}.

  • กราฟสามารถใช้ในการแก้ปัญหาจริงได้หลายปัญหา

  • กราฟสามารถใช้แสดงแทนเครือข่าย

  • เช่น เส้นทางในเมือง หรือเครือข่ายโทรศัพท์ หรือวงจรไฟฟ้า เป็นต้น

  • กราฟถูกใช้ใน social network เช่น LinkedIn และ Facebook

  • เช่น ใน Facebook บุคคลเป็น node ที่เก็บข้อมูลไอดี ชื่อ เพศ ต่าง ๆ และเชื่อมกันด้วยเส้นเชื่อมประเภทต่าง ๆ เช่น การเป็นเพื่อน

Type

Interactive reference: Introduction to Graphs by CS Academy 1

  • Undirected graph

  • Directed graph

  • Weighted graph คือกราฟที่ edge มีค่าน้ำหนัก เช่น ระยะทางหรือค่าใช้จ่าย

  • Unweighted graph คือกราฟที่ edge ทุกเส้นนับเท่ากัน

  • Simple graph คือไม่มี self-loop และไม่มี edge ซ้ำระหว่างคู่เดิม

Terminology

  • vertex หรือ node: จุดในกราฟ

  • edge: เส้นเชื่อมระหว่าง vertex

  • degree: จำนวน edge ที่ติดกับ vertex หนึ่ง

  • path: ลำดับของ vertex ที่เดินตาม edge ได้

  • cycle: path ที่เริ่มและจบที่ vertex เดิม

  • connected component: กลุ่ม vertex ที่เดินถึงกันได้

ในกราฟมีทิศทางจะมีคำว่า indegree และ outdegree

  • indegree: จำนวน edge ที่ชี้เข้ามา

  • outdegree: จำนวน edge ที่ชี้ออกไป

Representation

Interactive reference: Graph Representation by CS Academy 2

  • adjacency matrix

  • adjacency list

Adjacency matrix

ใช้ตาราง n \times n เก็บว่า edge ระหว่างคู่ vertex มีหรือไม่

  • ตรวจว่ามี edge จาก u ไป v ได้ใน O(1)

  • ใช้หน่วยความจำ O\left( n^{2} \right)

  • เหมาะกับกราฟหนาแน่นหรือ n เล็ก

vector<vector<int>> adj(n, vector<int>(n, 0));
adj[u][v] = 1;
adj[v][u] = 1; // ถ้าเป็น undirected graph
Adjacency list

เก็บรายชื่อเพื่อนบ้านของแต่ละ vertex

  • ใช้หน่วยความจำ O(V + E)

  • เหมาะกับกราฟส่วนใหญ่ในการแข่งขัน

  • เดิน edge ทั้งหมดได้เร็ว

vector<vector<int>> adj(n);
adj[u].push_back(v);
adj[v].push_back(u); // ถ้าเป็น undirected graph

ถ้าเป็น weighted graph ให้เก็บ pair

vector<vector<pair<int, int>>> adj(n);
adj[u].push_back({v, w});
Edge list

เก็บ edge ทั้งหมดเป็นรายการ (u, v, w) เหมาะกับอัลกอริทึมที่ไล่ทุก edge เช่น Kruskal และ Bellman-Ford

vector<tuple<int, int, int>> edges;  // (u, v, w)
edges.push_back({u, v, w});
Adjacency matrix Adjacency list Edge list
หน่วยความจำ O\left( V^{2} \right) O(V + E) O(E)
มี edge uv ไหม O(1) O\left( \text{deg}(u) \right) O(E)
ไล่เพื่อนบ้านของ u O(V) O\left( \text{deg}(u) \right) O(E)

อ่านกราฟจาก input

โจทย์ส่วนใหญ่ให้ n (จำนวน vertex) และ m (จำนวน edge) ตามด้วย edge ทีละบรรทัด

int n, m;
cin >> n >> m;
vector<vector<int>> adj(n + 1);  // vertex หมายเลข 1..n
for (int i = 0; i < m; i++) {
  int u, v;
  cin >> u >> v;
  adj[u].push_back(v);
  adj[v].push_back(u);
}

ตรวจให้ดีว่าโจทย์ใช้หมายเลข vertex เริ่มที่ 0 หรือ 1

Traversal

การเดินสำรวจกราฟ (BFS และ DFS) ใช้เวลา O(V + E) บน adjacency list อ่านต่อพร้อม widget ให้ลองเดินทีละขั้นในบท Graph Algorithm

โจทย์ฝึกฝน (Practice Problems)

ลองทำโจทย์เหล่านี้จาก CSES Problem Set เพื่อฝึกใช้ทักษะจากบทนี้ โดยเริ่มจากโจทย์ที่ง่ายที่สุดก่อน

โจทย์เพิ่มเติม: CSES Problem Set และ programming.in.th


  1. https://csacademy.com/lesson/introduction_to_graphs/↩︎

  2. https://csacademy.com/lesson/graph_representation/↩︎