BOJ-17471ゲルマンデリン
必要な知識
DFS
コンポジット
フルナビゲーション
に近づく
地域を2つの選挙区に分ける組み合わせを求めます.
コンビネーションを求めるたびに、問題で要求される条件をチェックします.
各選挙区には少なくとも1つの地域が含まれています.
すべての地域は2つの選挙区に含まなければならない.
同じ選挙区の間に隣接しなければならない.
1で求めた組合せが上記条件を満たすと、更新各選挙区人口の差が最小となる.
すべての組合せについて上記の手順を繰り返します.
go(pos)
:posの2番目の地域がどの選挙区であるかを指定し、組合せを求めます.コンビネーションをchkアレイに保存check()
:2カリキュラム要件チェック関数コード(C+)
#include <iostream>
#include <vector>
#include <limits.h>
#include <string.h>
#include <algorithm>
using namespace std;
vector<vector<int>>v;
int n, t, x, ans = INT_MAX, val[3], ppl[11], chk[11], dfschk[11];
void dfs(int cur, int m) {
for (int i = 0; i < v[cur].size(); i++) {
int next = v[cur][i];
if (!dfschk[next] && chk[next] == m) {
dfschk[next] = m;
val[m] += ppl[next];
dfs(next, m);
}
}
return;
}
bool check() {
//선거구는 무조건 1개 부터 n-1개까지 두선거구의 합은 n
int v1 = 0, v2 = 0;
for (int i = 0; i < n; i++) {
if (chk[i] == 1) v1 += 1;
else v2 += 1;
}
if (!v1 || !v2 || v1 + v2 != n) return false;
//각 선거구는 이어져야함
memset(dfschk, 0, sizeof(dfschk));
val[1] = val[2] = 0;
//선거구 dfs
for (int k = 1; k <= 2; k++) {
for (int i = 0; i < n; i++) {
if (chk[i] == k) {
dfschk[i] = k;
val[k] += ppl[i];
dfs(i, k);
break;
}
}
}
//조합으로 지정한 선거구와 dfs의 결과 비교
for (int i = 0; i < n; i++) {
if (chk[i] == dfschk[i]) continue;
else return false;
}
return true;
}
void go(int pos) {
if (pos == n) return;
if (check()) ans = min(ans, abs(val[1] - val[2]));
for (int i = 1; i <= 2; i++) {
chk[pos] = i;
go(pos + 1);
chk[pos] = 2;
}
return;
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n; v.resize(n + 1);
for (int i = 0; i < n; i++) cin >> ppl[i];
for (int i = 0; i < n; i++) {
cin >> t;
for (int j = 0; j < t; j++) {
cin >> x;
v[i].push_back(x - 1);
}
}
for (int i = 0; i < n; i++) chk[i] = 2;
go(0);
ans = (ans == INT_MAX) ? -1 : ans;
cout << ans;
return 0;
}
Reference
この問題について(BOJ-17471ゲルマンデリン), 我々は、より多くの情報をここで見つけました https://velog.io/@hschoi1104/BOJ-17471-게리맨더링テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol