본문으로 건너뛰기
김신건의 로그

차수열 (Degree Sequence)

· 수정 · 📖 약 2분 · 737자/단어 #algorithm #graph #degree-sequence
degree sequence, 차수열, graphic sequence, Erdos-Gallai, Havel-Hakimi

정의

차수열 (Degree Sequence) 은 그래프의 각 정점 차수를 내림차순으로 나열한 수열 d[1] >= d[2] >= … >= d[N]. 이 수열을 만족하는 단순 그래프(loop / multigraph 없음)가 존재하면 graphic sequence 라고 한다.

문제 상황과 동기

“이 차수열을 가진 단순 그래프가 실제로 존재하는가?” 를 판별해야 할 때:

  • naive: 모든 가능한 그래프를 생성해 차수열 비교. 지수적 불가능.
  • Havel-Hakimi / Erdos-Gallai: O(N^2) 에 necessary and sufficient 조건 판별.

핵심 통찰: 가장 큰 차수 정점을 그 다음 큰 정점들에 연결하고 제거하는 과정을 반복하면, 차수열의 실현 가능성이 결정된다.

시각화

핵심 아이디어

Havel-Hakimi 정리 (구성적)

내림차순 차수열 d[1..N] 이 graphic 할 필요충분조건:

d[1] <= N-1 이고
d[1] 을 제거한 후, d[1] 개의 다음 정점들의 차수를 1씩 감소시킨 새 수열이 graphic 함.

Erdos-Gallai 정리 (필요충분)

내림차순 d[1..N] 이 graphic 할 필요충분조건:

  1. 모든 d[i] ≤ N-1
  2. sum(d) 가 짝수
  3. 모든 1 ≤ k ≤ N 에 대해:
sum_{i=1..k} d[i] <= k(k-1) + sum_{i=k+1..N} min(d[i], k)

알고리즘

is_graphic(d):
    d 를 내림차순 정렬
    if any d[i] < 0: return false
    if sum(d) % 2 == 1: return false
    if all d[i] == 0: return true
    x = d[0]  # 가장 큰 차수
    d[0] = 0
    for i = 1..x:
        d[i] -= 1
        if d[i] < 0: return false
    return is_graphic(d)  # 재귀

구현

// Havel-Hakimi 로 graphic sequence 판별
#include <bits/stdc++.h>
using namespace std;
bool havel_hakimi(vector<int> d) {
  while (true) {
      sort(d.rbegin(), d.rend());          // 내림차순
      while (!d.empty() && d.back() == 0)   // 0 제거
          d.pop_back();
      if (d.empty()) return true;           // 모두 0
      int x = d.front();                    // 최대 차수
      d.erase(d.begin());
      if (x > (int)d.size()) return false;  // 정점 부족
      for (int i = 0; i < x; i++) {
          d[i]--;
          if (d[i] < 0) return false;
      }
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n; cin >> n;
  vector<int> d(n);
  for (auto& v : d) cin >> v;
  cout << (havel_hakimi(d) ? 1 : -1) << "\n";
  return 0;
}
stdin
5
3 3 2 2 2
결과
1

복잡도

항목
Havel-Hakimi 시간O(N^2) (매 단계 정렬)
Erdos-Gallai 시간O(N^2) (k 마다 합)
최적화 Erdos-GallaiO(N log N) (prefix sum + binary search)
공간O(N)

변형 / 활용

정리접근특징
Havel-Hakimi구성적 (constructive)실제 그래프 복원 가능
Erdos-Gallai판별적 (decision)부등식만 확인
Gale-Ryser이분 그래프용bipartite degree sequence

함정

1. 정렬 유지

각 단계마다 내림차순 정렬을 유지해야 함. 차수를 감소시킨 후 정렬하지 않으면 결과가 달라짐.

2. 차수 합 홀짝

차수 합이 홀수면 무조건 불가능 (handshaking lemma).

3. N=1 일 때

N=1 이면 차수열 [0] 만 유효. d[1] > 0 이면 불가능 (loop 필요).

BOJ 연습 문제

번호제목정답률링크
BOJ 2084차수열46.8%kokoa-lab
BOJ 13560축구 게임26.8%kokoa-lab
BOJ 31217Y59.0%kokoa-lab
BOJ 3386테니스 클럽25.6%kokoa-lab

참고

이 글의 용어 (3개)
그래프 순회 (Graph Traversal)algorithm
정의 그래프 순회 (Graph Traversal) 는 그래프 G=(V, E) 의 모든 정점 V 를 체계적으로 방문하는 알고리즘 패밀리. 대표 구현: 너비 우선 탐색 (BFS), …
이분 그래프 (Bipartite Graph)algorithm
정의 이분 그래프 (Bipartite Graph) 는 정점 집합 V 를 두 개의 독립 집합 L, R 로 분할할 수 있고, 모든 간선이 L 과 R 을 잇는 그래프. 같은 집합 내 …
최소 신장 트리 (MST, Minimum Spanning Tree)algorithm
정의 최소 신장 트리 (Minimum Spanning Tree, MST) 는 연결 그래프 G = (V, E) 에서 모든 정점을 연결 하면서 간선 가중치 합이 최소 인 부분 그래프…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기