คำชี้แจงปัญหา
ต้นไม้มักจะเป็นกราฟสองส่วน เนื่องจากเราสามารถแบ่งออกเป็นชุดที่ไม่ปะติดปะต่อกันด้วยระดับอื่นได้
กล่าวอีกนัยหนึ่งเราระบายสีด้วยสองสีเสมอเพื่อให้ระดับอื่นมีสีเดียวกัน งานคือการคำนวณจำนวนสูงสุด ของขอบที่สามารถเพิ่มลงในแผนภูมิเพื่อให้ยังคงเป็นกราฟแบบสองส่วน
ตัวอย่าง
ขอบต้นไม้แสดงคู่จุดยอดดังนี้ -
{1/}
{1/}
{2, 4}
{3, 5} เราต้องการอีก 2 ขอบเพื่อให้เป็นกราฟสองส่วน
- ในกราฟสี กราฟ {1, 4, 5} และ {2, 3} จากชุดที่แตกต่างกันสองชุด เนื่องจาก 1 เชื่อมต่อจากทั้ง 2 และ 3
- เหลือขอบ 4 และ 5 เนื่องจาก 4 เชื่อมต่อกับ 2 และ 5 ถึง 3 แล้ว เหลือตัวเลือกเดียวคือ {4, 3} และ {5, 2}
อัลกอริทึม
- ทำการข้ามผ่าน DFS หรือ BFS ของกราฟและระบายสีด้วยสองสี
- ในขณะที่การระบายสียังติดตามการนับโหนดที่มีสองสี ให้นับทั้งสองเป็น count_color0 และ count_color1
- ตอนนี้เรารู้แล้วว่าขอบสูงสุดที่กราฟสองส่วนสามารถมีได้คือ count_color0 x count_color1
- เรารู้ด้วยว่าต้นไม้ที่มี n โหนดมีขอบ n-1
- คำตอบของเราคือ count_color0 x count_color1 – (n-1)
ตัวอย่าง
#include <bits/stdc++.h> using namespace std; long long count_color[2]; void dfs(vector<int> graph[], int node, int parent, int color) { ++count_color[color]; for (int i = 0; i < graph[node].size(); ++i) { if (graph[node][i] != parent) { dfs(graph, graph[node][i], node, !color); } } } int getMaxEdges(vector<int> graph[], int n) { dfs(graph, 1, 0, 0); return count_color[0] * count_color[1] - (n - 1); } int main() { int n = 5; vector<int> graph[n + 1]; graph[1].push_back(2); graph[1].push_back(3); graph[2].push_back(4); graph[3].push_back(5); cout << "Maximum edges = " << getMaxEdges(graph, n) << endl; return 0; }
ผลลัพธ์
เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้น มันสร้างผลลัพธ์ต่อไปนี้ -
Maximum edges = 2