[20210323] 브루트포스


https://www.acmicpc.net/problem/17471

 

17471번: 게리맨더링

선거구를 [1, 4], [2, 3, 5, 6]으로 나누면 각 선거구의 인구는 9, 8이 된다. 인구 차이는 1이고, 이 값보다 더 작은 값으로 선거구를 나눌 수는 없다.

www.acmicpc.net

 

 

[난이도] Gold5
[유형] 브루트포스

[풀이]
N제한이 10밖에 안되므로 비트마스크를 이용해 완전탐색으로 그룹을 나눌 수 있는 모든 경우의 수를 구해준다.
그 뒤 두 그룹의 대표 한개를 정해 다른 그룹을 거치지 않고 자신의 모든 그룹원소에 도달이 가능한지를 DFS를
이용해 체크해주면 된다. 되는 케이스에 대해 인구수 차이의 최소값을 갱신해주면 된다.

 

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
int N,a[10];
bool flag[10],visit[10];
vector<int> adj[10];
vector<int> vst[2];
void dfs(int n,int k){
    visit[n]=1;
    vst[k].push_back(n);
    for(auto nxt : adj[n]){
        if(flag[nxt]==k&&!visit[nxt]) dfs(nxt,k);
    }
}

int main(){
    scanf("%d",&N);
    for(int i=0;i<N;i++) scanf("%d",&a[i]);
    for(int i=0;i<N;i++){
        int c;
        scanf("%d",&c);
        for(int j=0;j<c;j++){
            int k;
            scanf("%d",&k);
            k--;
            adj[i].push_back(k);
            adj[k].push_back(i);
        }
    }
    int ans = 9e8;
    for(int i=1;i<(1<<N);i++){
        int u=-1,v=-1;
        for(int j=0;j<N;j++){   
            if(i&(1<<j)) {
                flag[j]=1;
                if(u==-1) u=j;
            }
            else {
                flag[j]=0;
                if(v==-1) v=j;
            }
        }
        if(u==-1 || v==-1) continue;
        
        vst[0].clear();
        vst[1].clear();
        memset(visit,0,sizeof(visit));
        
        dfs(v,0);
        dfs(u,1);
        if(vst[0].size()+vst[1].size() != N) continue;

        int usum=0,vsum=0;
        bool ok=1;
        for(auto k : vst[0]){
            if(flag[k]) {
                ok=0;
                break;
            }
            usum+=a[k];
        }
        if(!ok) continue;

        ok=1;
        for(auto k : vst[1]){
            if(!flag[k]) {
                ok=0;
                break;
            }
            vsum+=a[k];
        }
        if(!ok) continue;
        ans=min(ans,abs(usum-vsum));
    }
    printf("%d",ans == 9e8 ? -1 : ans);
}


https://github.com/has2/Problem-Solving/blob/master/boj-solved.ac/Gold5/17471.cpp

+ Recent posts