728x90
https://www.acmicpc.net/problem/2414
최소 버텍스 커버 문제 + 이분매칭 문제입니다.
백준 1867 <돌멩이 제거> Python
https://www.acmicpc.net/problem/1867'해당 문제는 이분매칭 알고리즘을 사용하는 문제입니다.'라고 말하면 왜인지 다들 화가 날 것 같습니다. 저는 화가 났습니다. 왜냐하면 이 문제는 단순한 이분매칭
dev-diary-0717.tistory.com
위의 돌멩이 제거 문제와 같은 문제지만 중간에 끊기는 부분이 있기에 그 부분에서 새로 행 / 열을 추가한다고 생각하고 연결 가능 리스트를 만들어주면 기존의 방식과 같이 풀 수 있습니다.
import sys
input = sys.stdin.readline
# 이분매칭
def bimatch(idx, connectable, connected, visited):
# 방문했다면 패스
if visited[idx]:
return False
# 방문 체크
visited[idx] = True
# 순회
for node in connectable[idx]:
# 선택할 수 있거나 옮길 수 있으면
if connected[node] < 0 or bimatch(connected[node], connectable, connected, visited):
# 선택
connected[node] = idx
return True
return False
def solution(N, M, table):
# 이분매칭
# 행 / 열 로 나누어야 하지만
# 중간에 끊긴 부분이 있으므로
# 끊긴 부분은 다른 행 / 열로 간주
# [행 / 열] 목록
rc_table = [[[-1, -1] for _ in range(M)] for __ in range(N)]
# 순회하며 업데이트
# 누적 행
before_row = 0
for n in range(N):
# 직전 상태
before_state = True
for m in range(M):
# 현재 구멍이 뚫려있으면
if table[n][m] == '*':
# 직전 상태가 구멍이 아니면
if not before_state:
before_row += 1
# 행 업데이트
rc_table[n][m][0] = before_row
# 직전 상태 업데이트
before_state = True
# 현재 구멍이 안뚫려있으면
else:
# 직전 상태 업데이트
before_state = False
before_row += 1
# 누적 열
before_column = 0
for m in range(M):
# 직전 상태
before_state = True
for n in range(N):
# 현재 구멍이 뚫려있으면
if table[n][m] == '*':
# 직전 상태가 구멍이 아니면
if not before_state:
before_column += 1
# 행 업데이트
rc_table[n][m][1] = before_column
# 직전 상태 업데이트
before_state = True
# 현재 구멍이 안뚫려있으면
else:
# 직전 상태 업데이트
before_state = False
before_column += 1
# 행 / 열 최댓값
max_row = max([rc_table[n][m][0] for m in range(M) for n in range(N)])
max_column = max([rc_table[n][m][1] for m in range(M) for n in range(N)])
# 연결되어 있는 행 -> 열
connectable = [[] for _ in range(max_row+1)]
for n in range(N):
for m in range(M):
# 구멍이면
if table[n][m] == '*':
# 추가
connectable[rc_table[n][m][0]].append(rc_table[n][m][1])
# 선택한 위치
connected = [-1 for _ in range(max_column+1)]
# 순회
for idx in range(max_row+1):
# 방문목록
visited = [False for _ in range(max_row+1)]
# 이분매칭
bimatch(idx, connectable, connected, visited)
# 매칭된 수 리턴
print(sum([1 for c in connected if c >= 0]))
# 입력
N, M = map(int, input().strip().split())
table = [input().strip() for _ in range(N)]
solution(N, M, table)
728x90
'Coding Test > BaekJoon_Python' 카테고리의 다른 글
백준 11408 <열혈강호 5> Python (0) | 2024.10.27 |
---|---|
백준 2051 <최소 버텍스 커버> Python (0) | 2024.10.21 |
백준 3713 <당일치기> Python (0) | 2024.10.18 |
백준 1014 <컨닝> / 11014 <컨닝 2> Python (0) | 2024.10.16 |
백준 32349 <구슬 옮기기> Python (0) | 2024.10.15 |