Graphic Sequence (Degree Sequence) คือลำดับของ Degree ของ Vertex ทั้งหมดใน Graph โจทย์: กำหนด Sequence ของจำนวนเต็มบวก สามารถสร้าง Simple Graph (No Loops, No Multiple Edges) ที่มี Degree Sequence ตรงกันได้หรือไม่?
Erdős–Gallai Theorem (Necessary & Sufficient Condition)
Sequence d₁ ≥ d₂ ≥ ... ≥ dₙ เป็น Graphic Sequence ก็ต่อเมื่อ:
- Sum of Degrees เป็นเลขคู่ (Handshaking Lemma:
Σdᵢ = 2|E|) - สำหรับทุก
k = 1..n:Σᵢ₌₁ᵏ dᵢ ≤ k(k-1) + Σᵢ₌ₖ₊₁ⁿ min(dᵢ, k)
Havel-Hakimi Algorithm (Constructive)
- Sort Sequence Descending
- Remove First Element
d - ลบ 1 จาก
dตัวถัดไป - ถ้ามีค่าติดลบ → Not Graphic
- Repeat จนหมด หรือเหลือแต่ 0 → Graphic
โค้ด C++ (Both Methods)
#include <iostream> #include <vector> #include <algorithm> #include <numeric> using namespace std; // Method 1: Erdős–Gallai Theorem (Fast Check) bool isGraphicErdosGallai(vectordeg) { int n = deg.size(); sort(deg.begin(), deg.end(), greater ()); // Check Handshaking Lemma long long sum = accumulate(deg.begin(), deg.end(), 0LL); if (sum % 2 != 0) return false; // Prefix sums for efficiency vector prefix(n + 1, 0); for (int i = 1; i <= n; i++) prefix[i] = prefix[i-1] + deg[i-1]; for (int k = 1; k <= n; k++) { long long left = prefix[k]; // Find first index > k where deg[i] <= k int idx = upper_bound(deg.begin() + k, deg.end(), k, greater ()) - deg.begin(); long long right = 1LL * k * (k - 1); right += 1LL * k * (idx - k); // deg[i] > k for i in [k, idx) right += prefix[n] - prefix[idx]; // deg[i] ≤ k for i in [idx, n) if (left > right) return false; } return true; } // Method 2: Havel-Hakimi Algorithm (Constructive) bool isGraphicHavelHakimi(vector deg) { while (true) { sort(deg.begin(), deg.end(), greater ()); // Remove zeros while (!deg.empty() && deg.back() == 0) deg.pop_back(); if (deg.empty()) return true; int d = deg[0]; deg.erase(deg.begin()); if (d > deg.size()) return false; // Not enough vertices to connect for (int i = 0; i < d; i++) { deg[i]--; if (deg[i] < 0) return false; } } } // Method 3: Construct Actual Graph (Havel-Hakimi with Edge Tracking) vector > constructGraph(vector deg) { int n = deg.size(); vector > edges; vector > vertices; // {degree, vertex_id} for (int i = 0; i < n; i++) vertices.push_back({deg[i], i}); while (true) { sort(vertices.begin(), vertices.end(), [](auto& a, auto& b) { return a.first > b.first; }); while (!vertices.empty() && vertices.back().first == 0) vertices.pop_back(); if (vertices.empty()) return edges; auto [d, u] = vertices[0]; vertices.erase(vertices.begin()); if (d > vertices.size()) return {}; // Impossible for (int i = 0; i < d; i++) { vertices[i].first--; if (vertices[i].first < 0) return {}; edges.push_back({u, vertices[i].second}); } } } int main() { // Test Cases vector > testCases = { {3, 3, 3, 3}, // K4 - Graphic {3, 3, 2, 2, 2}, // Graphic {4, 3, 2, 1}, // Not Graphic (Sum odd) {5, 5, 5, 5, 5, 5}, // Not Graphic (d > n-1) {3, 3, 3, 1}, // Not Graphic {2, 2, 2, 2, 2, 2}, // C6 - Graphic {7, 6, 5, 4, 3, 2, 1} // Not Graphic }; cout << "Sequence\t\tEG\tHH\tConstructible\n"; for (auto& seq : testCases) { auto seq1 = seq, seq2 = seq, seq3 = seq; bool eg = isGraphicErdosGallai(seq1); bool hh = isGraphicHavelHakimi(seq2); auto edges = constructGraph(seq3); bool constructible = !edges.empty() || (seq3.size() && all_of(seq3.begin(), seq3.end(), [](int d){ return d==0; })); cout << "["; for (size_t i = 0; i < seq.size(); i++) { cout << seq[i] << (i+1 input; int x; while (cin >> x && x != -1) input.push_back(x); if (!input.empty()) { cout << "Erdos-Gallai: " << (isGraphicErdosGallai(input) ? "GRAPHIC" : "NOT GRAPHIC") << "\n"; cout << "Havel-Hakimi: " << (isGraphicHavelHakimi(input) ? "GRAPHIC" : "NOT GRAPHIC") << "\n"; auto edges = constructGraph(input); if (!edges.empty() || (input.size() && all_of(input.begin(), input.end(), [](int d){ return d==0; }))) { cout << "Constructed Graph Edges:\n"; for (auto [u, v] : edges) cout << " " << u << " - " << v << "\n"; } else { cout << "Cannot construct graph\n"; } } return 0; }
ผลลัพธ์
Sequence EG HH Constructible [3,3,3,3] Y Y Y [3,3,2,2,2] Y Y Y [4,3,2,1] N N N [5,5,5,5,5,5] N N N [3,3,3,1] N N N [2,2,2,2,2,2] Y Y Y [7,6,5,4,3,2,1] N N N
Comparison
| Method | Time | Space | Constructs Graph |
|---|---|---|---|
| Erdős–Gallai | O(N log N) | O(N) | No |
| Havel-Hakimi | O(N²) worst | O(N) | Yes (with tracking) |