에듀테크 프로젝트 대시보드
이분 매칭
증대 경로(Augmenting Path) 탐색 · Kuhn's Algorithm · O(V·E)
정점 집합을 두 그룹으로 나눴을 때, 같은 그룹 안에서는 절대 간선이 없고 서로 다른 그룹 사이에만 간선이 있는 그래프를 이분 그래프(Bipartite Graph)라고 한다. 학생 ↔ 동아리, 구직자 ↔ 일자리, 손님 ↔ 테이블처럼 "두 종류를 서로 연결"하는 문제는 대부분 이 형태다.
왼쪽 정점(학생)을 한 명씩 순서대로 처리한다. 그 학생이 갈 수 있는 동아리를 순서대로 확인하다가 빈 동아리를 만나면 바로 배정한다. 이미 다른 학생이 있는 동아리라면, 그 학생이 다른 동아리로 옮길 수 있는지 재귀적으로 확인한다 — 옮길 수 있다면 자리를 비켜주고 지금 학생이 그 자리를 차지한다. 이렇게 "자리 양보"가 연쇄적으로 일어나는 것이 바로 증대 경로를 실제로 뒤집는 과정이다.
def try_kuhn(u, visited): # u(왼쪽 정점)가 갈 수 있는 동아리를 순서대로 확인 for v in adj[u]: if v in visited: continue visited.add(v) # v가 비었거나, v를 차지한 학생이 다른 곳으로 옮길 수 있다면 if v not in match_r or try_kuhn(match_r[v], visited): match_r[v] = u return True return False match_r = {} # 동아리 -> 학생 for u in students: try_kuhn(u, visited=set()) max_matching = len(match_r)