ตะลุยตลาด

o59_may02_chaospath

ในข้อนี้เราได้รับต้นไม้มา หน้าที่ของเราคือการหาความยาวของ longest path บนต้นไม้ต้นนี้ โดยที่ความยาวของเส้นเชื่อมมีค่าเท่ากับความยุ่งเหยิงของเส้นเชื่อมนั้น ๆ

ก่อนอื่นให้เราทำการ root tree ที่จุดยอด 11 โดยการมองจุดยอด 11 เป็นรากของต้นไม้ แล้วให้จุดยอดอื่น ๆ ลดหลั่นกันลงมาตามเส้นทางจาก 11 ไปหาจุดยอดนั้น ๆ

การ root tree จะทำให้จุดยอดใด ๆ ยกเว้นจุดยอด 11 มี "parent" ของตัวมันเอง โดย parent คือจุดยอดแรกที่มันต้องผ่านในเส้นทางจากจุดยอดนั้น ๆ ถึง root เราจะแทน parent ของจุดยอด uu ด้วย p(u)p(u)

จากนั้นสำหรับจุดยอด uu ใด ๆ ที่ไม่ใช่ 11 เราจะให้ e(u)e(u) แทนเส้นเชื่อมที่เชื่อมระหว่าง uu และ p(u)p(u)

สังเกตว่าสำหรับจุดยอด uu ใด ๆ ถ้าเราตัดเส้นเชื่อม e(u)e(u) ออก ต้นไม้ของเราจะถูกแบ่งออกเป็นสองส่วน คือ subtree ของ uu (รวม uu ด้วย) และ ส่วนที่เหลือของต้นไม้ โดยการจะเดินทางจากจุดยอดในส่วนหนึ่งไปหาจุดยอดในอีกส่วนหนึ่ง ต้องใช้ e(u)e(u) เสมอ

ดังนั้นค่าความยุ่งเหยิงของ e(u)e(u) จะมีค่าเท่ากับ S(u)(nS(u))S(u)\cdot (n-S(u)) เมื่อ S(u)S(u) คือขนาดของ subtree ของ uu และ nn คือจำนวนจุดยอดทั้งหมดในต้นไม้ S(u)S(u) สามารถคำนวณได้จาก S(u)=1+ΣS(v)S(u) = 1 + \Sigma S(v) เมื่อ vv คือจุดยอดที่มี uu เป็น parent

ค่าความยุ่งเหยิงของเส้นเชื่อมทั้งหมดจะสามารถคำนวณได้โดย DFS ในเวลา O(n)\mathcal{O}(n)

จากนั้นเราจะต้องทำการหาเส้นทางที่ยาวที่สุดบนต้นไม้นี้ ซึ่งมีหลายวิธี แต่วิธีที่ผู้เขียนคิดว่าเรียบง่ายที่สุดคือวิธีการหา longest path สองครั้ง ซึ่งสามารถทำได้ดังนี้

  • เริ่มที่จุดยอด uu ใด ๆ แล้วหาจุดยอดที่มีระยะทางไกลจาก uu มากที่สุด เรียกจุดยอดนี้ว่า vv
  • หาจุดยอดที่มีระยะทางไกลจาก vv มากที่สุด ระยะทางระหว่าง vv และจุดยอดนี้จะเป็น longest path บน tree

ทั้งสองขั้นตอนสามารถทำได้โดย Dijkstra's Algorithm หรือ DFS

ดังนั้นเราจะสามารถแก้ปัญหานี้ได้ในเวลา O(n)\mathcal{O}(n)