게리맨더링(BOJ 17471)
2024. 11. 15. 11:33ㆍBOJ/BFS,DFS
문제
문제 설명
- 구역은 1~n번까지 존재하는 데 각 구역에는 특정 인구수가 존재한다.
- 여러 개의 구역을 두 개의 그룹, 즉 선거구로. 분리할 건데 다음 조건을 만족해야 한다.
같은 선거구에 포함된 구역들은 서로 간접 혹은 직접적으로 연결되어야 한다.
문제 해설
- 저와 같은 경우에는 비트마스크를 활용하여서 완전 탐색을 일차적으로 해주었습니다.
예를 들어 n=6이고 1번과 3번을 같은 그룹으로 만들고 싶다면 000101(2)로 일차적으로 체크해 주고 탐색을 해주면 된다.
- 그런 다음 bfs를 탐색을 해주었는 데 탐색은 일반적인 bfs탐색을 group1과 group2로 따로 나누어서 적용해 주었다.
- 만약 방문 처리 되지 않은 부분이 있다면 그 경우의 수는 생략해 준다.
최종 코드
#include <bits/stdc++.h>
using namespace std;
int n, mn = 1e9 + 7;
vector<int> v[14];
vector<int> d(14);
int solution(int bit) {
int sum1 = 0, sum2 = 0;
vector<int> visited(14, 0);
bool flag1 = false, flag2 = false;
for (int i = 0; i < n; i++) {
if (bit & (1 << i)) { #만약 비트값이 1, 즉 선거구1에 포함되는 경우
sum1 += d[i];
if (!flag1) {
#만약 탐색을 한적이 없다면 탐색 시작(탐색한 적이 있으면 서로 연결 되지 않았다는 것을 의미)
flag1 = true;
queue<int> q;
q.push(i + 1);
visited[i + 1] = 1;
while (!q.empty()) {
int x = q.front();
q.pop();
for (auto next : v[x]) {
if ((bit & (1 << (next - 1))) && !visited[next]) {
visited[next] = 1;
q.push(next);
}
}
}
}
}
}
for (int i = 0; i < n; i++) {
if (!(bit & (1 << i))) { #비트값이 0, 즉 선거구2에 포함되는 경우
sum2 += d[i];
if (!flag2) {
flag2 = true;
queue<int> q;
q.push(i + 1);
visited[i + 1] = 2;
while (!q.empty()) {
int x = q.front();
q.pop();
for (auto next : v[x]) {
if (!(bit & (1 << (next - 1))) && !visited[next]) {
visited[next] = 2;
q.push(next);
}
}
}
}
}
}
for (int i = 1; i <= n; i++) {
if ((bit & (1 << (i - 1))) && visited[i] != 1) return 1e9 + 7;
if (!(bit & (1 << (i - 1))) && visited[i] != 2) return 1e9 + 7;
#방문되지 않았다면 큰 값을 return
}
return abs(sum1 - sum2); #차이를 return
}
int main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n;
for (int i = 0; i < n; i++) cin >> d[i]; #인구수 입력
for (int i = 1, x; i <= n; i++) { #연결된 구역을 입력
cin >> x;
for (int j = 0, y; j < x; j++) {
cin >> y;
v[i].push_back(y);
}
}
for (int i = 1; i < (1 << n) - 1; i++) mn = min(mn, solution(i)); #비트마스크를 활용한 경우의 수
cout << (mn == 1e9 + 7 ? -1 : mn);
}
'BOJ > BFS,DFS' 카테고리의 다른 글
| 두 로봇(BOJ15971) (0) | 2024.11.18 |
|---|---|
| 섬의 개수(BOJ4943) (1) | 2024.11.16 |
| 벽 부수고 이동하기 4 (0) | 2024.08.17 |
| BFS 스페셜 저지 (BOJ 16940) (1) | 2024.08.15 |
| 다리 만들기(BOJ 2146번) (0) | 2024.06.20 |

