[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
'Problem-Solving > BOJ' 카테고리의 다른 글
[BOJ/백준][Gold5] 7662 : 이중 우선순위 큐 (C++) (0) | 2021.04.25 |
---|---|
[BOJ/백준][Gold5] 13023 : ABCDE (C++) (0) | 2021.03.25 |
[BOJ/백준][Gold5] 2470 : 두 용액 (C++) (0) | 2021.03.25 |
[BOJ/백준][Gold5] 14226 : 이모티콘 (C++) (0) | 2021.03.25 |
[BOJ/백준][Gold5] 12851 : 숨바꼭질 2 (C++) (0) | 2021.03.25 |