728x90
17471. 게리맨더링
난이도 : 골드 3
소요 시간 : 20분
날짜 : 2024.01.02
언어 : 파이썬
알고리즘 유형 : 그래프이론, bfs, dfs, 조합
설명 보기전에 문제 풀어보러 가기
1. 문제 설명
- 각각의 인구가 있는 구역이 있음.
- 구역을 두 선거구로 나누어야 함.
- 같은 선거구에 속한 구역은 항상 연결되어있어야 함.
- 한 선거구에는 최소 1개 이상의 구역이 있어야 함.
- 각 선거구의 인구의 차이를 최소로 하기
2. 해결 방식
- 구역의 개수가 최대 10밖에 안되어서 그냥 완전탐색을 하기로 했다.
- 가능한 모든 선거구의 조합을 구해서 확인한다.
- 먼저 선거구가 연결되어있는지 확인 : 기본적인 bfs로 해결
- 연결되어있다면 최소값 갱신
3. 정답 코드
import sys;input = sys.stdin.readline
from itertools import combinations
from collections import deque as dq
n = int(input())
populations = list(map(int, input().split()))
arr = [[0] * n for _ in range(n)]
for i in range(n):
inp = list(map(int, input().split()))
num = inp[0]
for j in range(1, num + 1):
arr[i][inp[j] - 1] = 1
arr[inp[j] - 1][i] = 1
inf = 1e10
res = inf
total = sum(populations)
def sol(left:list):
global res
right = [i for i in range(n) if i not in left]
if len(left) in [0, n]:return
if not check(left, len(left)):return
if not check(right, len(right)):return
res = min(res, abs(total - 2 * sum([populations[i] for i in left])))
def check(x:list, d:int):
q = dq()
visit = [0] * len(x)
visit[0] = 1
q.append(0)
while q:
now = q.popleft()
for i in range(len(x)):
if visit[i] or not arr[x[now]][x[i]]:continue
visit[i] = 1
q.append(i)
return False if 0 in visit else True
for i in range(1 + n // 2):
for com in combinations([j for j in range(n)], i):
sol(list(com))
print(res if res != inf else -1)
반응형
'백준 문제풀이 코드저장소 > Gold' 카테고리의 다른 글
Baekjoon 25682. 체스판 다시 칠하기 2 / Python (0) | 2025.01.06 |
---|---|
Baekjoon 23250. 하노이 탑 K / Python (0) | 2025.01.02 |
Baekjoon 1038. 감소하는 수 / Python (0) | 2025.01.02 |
Baekjoon 2042. 구간 합 구하기 / Python (0) | 2025.01.01 |