반응형
17471번: 게리맨더링
선거구를 [1, 4], [2, 3, 5, 6]으로 나누면 각 선거구의 인구는 9, 8이 된다. 인구 차이는 1이고, 이 값보다 더 작은 값으로 선거구를 나눌 수는 없다.
www.acmicpc.net
풀이 )
1번 도시를 포함한 선거구 v1, 1번 도시를 포함하지 않은 선거구 v2로 나누었다. 이때 나눌때는 완전탐색을 했다.
이후 나눈 두 선거구가 가능한지 여부를 BFS를 사용해서 확인해서 가능한 경우, 두 선거구의 인원수 차이를 갱신한다.
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int n;
int total_pop = 0;
int popul[10];
bool adj[10][10];
vector<int> v1;
vector<int> v2;
vector<int> tmp1(1); // v1 초기화용
vector<int> tmp2; // v2 초기화용
int ans = 1e9;
bool check(vector<int> v){
int len = v.size();
if(len == 1) // 도시가 1개일 경우 반드시 가능
return true;
vector<bool> vb(len);
queue<int> q;
q.push(v[0]);
vb[0] = true;
while(!q.empty()){ // BFS로 선거구 도시 방문
int cur = q.front();
q.pop();
for(int i = 1; i < len; ++i){
if(!vb[i] && adj[cur][v[i]]){
q.push(v[i]);
vb[i] = true;
}
}
}
for(int i = 0; i < len; ++i)
if(!vb[i])
return false;
return true; // 모든 도시 방문 했는지
}
void divide(int pos, int cnt, int target){
if(cnt == target){
v2 = tmp2;
int len = v1.size();
int city = 1;
int cur = 1;
while(1){ // v1 선거구를 이용해 나머지 도시를 v2 선거구로
if(city == n)
break;
if(cur == len || city < v1[cur])
v2.push_back(city);
else
cur++;
city++;
}
if(check(v1) && check(v2)){ // 두 선거구 가능
int len = v1.size();
int v1Sum = 0;
for(int j = 0; j < len; ++j)
v1Sum += popul[v1[j]];
if(abs(total_pop-2*v1Sum) >= ans)
return;
ans = abs(total_pop-2*v1Sum);
}
return;
}
for(int i = pos; i < n; ++i){ // 완전탐색으로 v1 선거구 도시 선택
v1.push_back(i);
divide(i+1, cnt+1, target);
v1.pop_back();
}
}
int main(void){
cin >> n;
for(int i = 0; i < n; ++i){
cin >> popul[i];
total_pop += popul[i];
}
for(int i = 0; i < n; ++i){
int num;
cin >> num;
while(num--){
int city;
cin >> city;
adj[i][city-1] = true;
adj[city-1][i] = true;
}
}
for(int i = 1; i < n; ++i){
v1 = tmp1;
v2 = tmp2;
divide(1, 1, i);
}
if(ans == 1e9)
ans = -1;
cout << ans << '\n';
return 0;
}
반응형
'문제풀이 > 백준' 카테고리의 다른 글
[C++] 백준 - 15686 : 치킨 배달 (0) | 2021.01.06 |
---|---|
[C++] 백준 - 1107 : 리모컨 (0) | 2020.12.28 |
[C++] 백준 - 14503 : 로봇 청소기 (0) | 2020.12.23 |
[C++] 백준 - 1719 : 택배 (0) | 2020.12.22 |
[C++] 백준 - 15684 : 사다리 조작 (0) | 2020.12.21 |