https://www.acmicpc.net/problem/17471
17471번: 게리맨더링
선거구를 [1, 4], [2, 3, 5, 6]으로 나누면 각 선거구의 인구는 9, 8이 된다. 인구 차이는 1이고, 이 값보다 더 작은 값으로 선거구를 나눌 수는 없다.
www.acmicpc.net
조합을 통한 완전탐색 + 유니온파인드로 접근하였다.
접근 방법
입력으로 주어지는 구역의 최대개수는 10이다. 따라서 각 구역이 두 가지 선거구로 선택되는 경우의 수를 계산하면 2^10 즉 1024의 경우의 수가 발생. 이후 각 조건에서 유니온 파인드를 수행한다.
유니온 파인드에서 두 노드가 결합되는 조건은 서로 인접하며 정해진 선거구가 같은 경우만 결합하는 것으로 하였다. 마지막으로 컴포넌트의 수가 2인 경우만 각 선거구의 인구수를 확인하여 정답을 반영하면 된다.
정답 코드
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
let N = Int(readLine()!)! | |
var population = readLine()!.split(separator: " ").map{Int($0)!} | |
var total = population.reduce(0, +) | |
var edges = [(u:Int, v:Int)]() | |
var ans = Int.max | |
for u in 0..<N{ | |
let info = readLine()!.split(separator: " ").map{Int($0)!} | |
let n = info[0] | |
if n == 0{ continue } | |
for i in 1...n{ edges.append((u,info[i]-1))} | |
} | |
var list = [[String]]() | |
func btk(team:[String]){ | |
var team = team | |
if team.count == N{ | |
list.append(team) | |
return | |
} | |
team.append("R") | |
btk(team: team) | |
team.removeLast() | |
team.append("B") | |
btk(team: team) | |
} | |
btk(team: []) | |
for team in list{ | |
var arr = population.map{-1*$0} | |
var cnt = N | |
var red = 0 | |
var blue = 0 | |
for i in 0..<N{ | |
if team[i] == "R"{ | |
red += population[i] | |
}else{ | |
blue += population[i] | |
} | |
} | |
func root(of node:Int) -> Int{ | |
if arr[node] < 0{ return node } | |
arr[node] = root(of: arr[node]) | |
return arr[node] | |
} | |
func union(a:Int, b:Int){ | |
let A = root(of: a) | |
let B = root(of: b) | |
if team[a] != team[b] { return } | |
if A==B { return } | |
arr[A] += arr[B] | |
arr[B] = A | |
cnt -= 1 | |
} | |
for edge in edges { | |
union(a: edge.u, b: edge.v) | |
} | |
if cnt == 2{ | |
ans = min(ans,abs(red-blue)) | |
} | |
} | |
print(ans==Int.max ? -1:ans) |

'Problem Solving > BOJ' 카테고리의 다른 글
[13397] 구간 나누기 2 (0) | 2024.02.28 |
---|---|
[8983] 사냥꾼 (0) | 2024.02.19 |
[1700] 멀티탭 스케줄링 (0) | 2024.01.30 |
[23286] 허들 넘기 (0) | 2024.01.18 |
[5582] 공통 부분 문자열 (0) | 2024.01.12 |