728x90
    
    
  https://www.acmicpc.net/problem/1298
전형적인 이분매칭 문제입니다.
해당 알고리즘은 DFS 를 기반으로 합니다.
우선 순차적으로 노드를 순회하며 매칭 가능한 노드를 연결합니다.
다음 노드에서 임의의 노드를 골랐는데 해당 노드가 이미 다른 노드와 연결되어있다면 연결된 노드를 다른 노드와 연결시킬 수 있는지 재귀적으로 탐색하며 최대한 옮긴 뒤 현재의 노드와 고른 노드를 연결시키는 방식입니다.
조금 가볍게 말하자면 지하철을 탔을 때 임의의 자리에 앉고 싶을 경우 이미 앉아있는 승객에게 양해를 구해 다른 자리로 옮기게 하는 방식이라고 할 수 있습니다.
import sys
from collections import deque
input = sys.stdin.readline
# 이분 매칭
def bimatch(idx, visited, connected, bi_graph):
    # 방문했으면 패스
    if visited[idx]:
        return False
    # 방문 체크
    visited[idx] = True
    # 연결될 수 있는 노드 체크
    for node in bi_graph[idx]:
        # 연결되지 않았거나
        # 연결된 노드와 연결된 노드가 다른 노드를 선택할 수 있으면
        if not connected[node] or bimatch(connected[node], visited, connected, bi_graph):
            # 연결
            connected[node] = idx
            return True    
    return False
def solution(N, M, data_list):
    # 이분매칭을 위한 연결리스트 / 그래프
    connected = [0 for _ in range(N+1)]
    bi_graph = [[] for _ in range(N+1)]
    for a, b in data_list:
        bi_graph[a].append(b)
    # 한사람씩 순회
    for i in range(1, N+1):
        # 이분매칭을 위한 방문리스트
        visited = [False for _ in range(N+1)]
        # 이분매칭
        bimatch(i, visited, connected, bi_graph)
    # 연결 리스트에서 연결된 수 출력
    print(sum([1 for c in connected if c]))
# 입력
N, M = map(int, input().strip().split())
data_list = [list(map(int, input().strip().split())) for _ in range(M)]
solution(N, M, data_list)
728x90
    
    
  'Coding Test > BaekJoon_Python' 카테고리의 다른 글
| 백준 11375 <열혈강호 1> / 백준 11376 <열혈강호 2> Python (0) | 2024.09.30 | 
|---|---|
| 백준 2188 <축사 배정> Python (0) | 2024.09.29 | 
| 백준 1719 <택배> Python (1) | 2024.09.26 | 
| 백준 1922 <네트워크 연결> Python (0) | 2024.09.25 | 
| 백준 1461 <도서관> Python (1) | 2024.09.24 |