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

Computer Olympiad Guide for Thai High School Students

Paths and circuits

Eulerian

Eulerian path และ Hamiltonian path เป็นโจทย์ที่ดูคล้ายกันมาก แต่เงื่อนไขต่างกันและความยากต่างกันมาก

  • Eulerian สนใจการเดินผ่านทุก edge

  • Hamiltonian สนใจการเดินผ่านทุก vertex

Path

เป็น path ที่ท่องไปในเส้นเชื่อมทุกเส้นเพียงหนึ่งครั้งเท่านั้น

Circuit

เป็น Eulerian path ที่เริ่มและจบที่โหนดเดียวกัน

Existence

เงื่อนไขที่จะมี Eulerian path สำหรับ

  • กราฟไม่มีทิศทาง

    • ดีกรีของทุกโหนดเป็นจำนวนคู่ หรือ

    • ดีกรีของสองโหนดเป็นจำนวนคี่ (🧠 เพราะอะไร?)

  • กราฟมีทิศทาง

    • ในแต่ละโหนด ดีกรีเข้าจะต้องเท่ากับดีกรีออก หรือ

    • มีโหนดหนึ่งมีดีกรีเข้ามากกว่าดีกรีออกเท่ากับหนึ่ง อีกโหนดหนึ่งมีดีกรีออกมากกว่าดีกรีเข้าเท่ากับหนึ่ง และโหนดที่เหลือมีดีกรีเข้่าเท่ากับดีกรีออก

Hierholzer’s algorithm

Hierholzer’s algorithm ใช้หา Eulerian circuit/path เมื่อรู้แล้วว่าเงื่อนไขมีคำตอบ

แนวคิดคือเดินตาม edge ที่ยังไม่ใช้ไปเรื่อย ๆ ถ้าติดทางตันให้ย้อนกลับและใส่ vertex ลงคำตอบตอนย้อนกลับ

vector<vector<int>> adj;
vector<int> path;

void dfs(int u) {
  while (!adj[u].empty()) {
    int v = adj[u].back();
    adj[u].pop_back();
    dfs(v);
  }
  path.push_back(u);
}

สำหรับกราฟไม่มีทิศทาง ต้องลบ edge ทั้งสองด้าน และควรมี id ของ edge เพื่อไม่ใช้ edge เดิมซ้ำ

เวลาทำงานคือ O(V + E) ถ้าลบ edge ได้มีประสิทธิภาพ

Hamiltonian

เป็น path ที่ท่องไปในทุกโหนดเพียงหนึ่งครั้งเท่านั้น

Existence

ไม่มี efficient method เนื่องจากยังเป็นปัญหาประเภท NP-hard

เปรียบเทียบ

ชนิด

ต้องผ่าน

ตรวจเงื่อนไขเร็วไหม

วิธีที่ใช้บ่อย

Eulerian path

ทุก edge หนึ่งครั้ง

เร็ว

degree + Hierholzer

Eulerian circuit

ทุก edge หนึ่งครั้งและกลับจุดเริ่ม

เร็ว

degree + Hierholzer

Hamiltonian path

ทุก vertex หนึ่งครั้ง

โดยทั่วไปยาก

backtracking หรือ DP bitmask

ตัวอย่างโจทย์

  • ถ้าโจทย์พูดถึงการใช้ถนนทุกเส้นหนึ่งครั้ง ให้นึกถึง Eulerian

  • ถ้าโจทย์พูดถึงการเยี่ยมเมืองทุกเมืองหนึ่งครั้ง ให้นึกถึง Hamiltonian

  • ถ้ากราฟมีขนาดเล็กมาก เช่น n ≤ 20 Hamiltonian อาจใช้ DP bitmask ได้