8000 Merge pull request #439 from neppiness/17471 · Korcp/basic-algo-lecture@8888c45 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8888c45

Browse files
Merge pull request encrypted-def#439 from neppiness/17471
update: 0x0D 17471.cpp
2 parents aa4777f + 50a6054 commit 8888c45

File tree

1 file changed

+105
-5
lines changed

1 file changed

+105
-5
lines changed

0x0D/solutions/17471.cpp

Lines changed: 105 additions & 5 deletions
< 8211 td data-grid-cell-id="diff-6f6ebca3ed3bb696b8f50fbd0ac03e4030bd38df60e474e442cbfa6f23d16265-11-98-1" data-selected="false" role="gridcell" style="background-color:var(--diffBlob-additionNum-bgColor, var(--diffBlob-addition-bgColor-num));text-align:center" tabindex="-1" valign="top" class="focusable-grid-cell diff-line-number position-relative left-side">98
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,111 @@
1-
// Authored by : BaaaaaaaaaaarkingDog
1+
// Authored by : scsc3204
22
// Co-authored by : -
3-
// http://boj.kr/****************
3+
// http://boj.kr/85b770d684b942b6994994606010adc0
44
#include <bits/stdc++.h>
55
using namespace std;
66

7-
int main(void){
7+
const int INF = 0x7f7f7f7f;
8+
const int MX = 10;
9+
10+
int n, ans = INF;
11+
int viscnt;
12+
13+
int po[MX + 2];
14+
bool vis[MX + 2];
15+
16+
vector<bool> comb;
17+
vector<int> adj[MX + 2];
18+
19+
queue<int> q;
20+
21+
void bfs(int st) {
22+
bool code = comb[st];
23+
vis[st] = 1;
24+
viscnt++;
25+
q.push(st);
26+
27+
while(!q.empty()) {
28+
int cur = q.front(); q.pop();
29+
for(int nxt : adj[cur]) {
30+
if(vis[nxt] || comb[nxt] != code) continue;
31+
vis[nxt] = 1;
32+
viscnt++;
33+
q.push(nxt);
34+
}
35+
}
36+
}
37+
38+
void solve(int m) {
39+
fill(comb.begin(), comb.end(), 0);
40+
41+
for(int i = n - m; i < n; i++)
42+
comb[i] = 1;
43+
44+
do {
45+
viscnt = 0;
46+
fill(vis, vis + n, 0);
47+
48+
for(int i = 0; i < n; i++)
49+
if(!comb[i]) { bfs(i); break; }
50+
for(int i = 0; i < n; i++)
51+
if(comb[i]) { bfs(i); break; }
52+
53+
if(viscnt != n) continue;
54+
55+
int tmp = 0;
56+
for(int i = 0; i < n; i++) {
57+
if(comb[i]) tmp += po[i];
58+
else tmp -= po[i];
59+
}
60+
tmp = abs(tmp);
61+
ans = min(tmp, ans);
62+
} while(next_permutation(comb.begin(), comb.end()));
63+
}
64+
65+
int main() {
866
ios::sync_with_stdio(0);
967
cin.tie(0);
10-
11-
}
68+
69+
cin >> n;
70+
for(int i = 0; i < n; i++)
71+
cin >> po[i];
72+
for(int i = 0; i < n; i++) {
73+
int m; cin >> m;
74+
while(m--) {
75+
int x; cin >> x;
76+
adj[i].push_back(x - 1);
77+
}
78+
}
79+
80+
comb.resize(n);
81+
for(int i = 1; i <= n / 2; i++)
82+
solve(i);
83+
if(ans == INF) ans = -1;
84+
cout << ans;
85+
}
86+
/*
87+
next_permutation을 활용해 comb가 1인 구역을 하나씩 늘린다.
88+
이로써 n개 구역 중 1개 구역부터 n/2개 구역까지 선택하며 선거구를 구성한다.
89+
구역이 속한 선거구는 comb 값에 따라 구분한다.
90+
91+
이같이 구현하는 경우, 0011과 1100을 다른 경우로 판단해 중복 연산이 발생한다.
92+
그러나, n이 가장 클 때인 10개 구역에 대해서
93+
1명부터 5명씩 팀을 나누는 경우가 10C1 + 10C2 + 10C3 + 10C4 + 10C5이고
94+
이들은 10 + 45 + 120 + 210 + 252 = 637이기 때문에,
95+
더 효율적으로 팀을 나눌 필요는 없다고 판단하였다.
96+
97+
문제를 그래프로 구현했다.
+
문제의 구역 번호는 1-indexed지만, 편의상 0-indexed로 바꿔 구현하였다(69-75번째 줄).
99+
100+
구역 중 comb 값이 0인 경우와 1인 경우를 하나씩 찾아 bfs를 수행(45-48번째 줄)한다.
101+
이때, 인접한 구역 중 동일 선거구에 속한 구역만 방문하고 큐에 넣는다(26-31번째 줄).
102+
103+
만약 comb 값이 0인 구역과 1인 구역에 대한 bfs를 마친 뒤에도
104+
방문횟수를 세는 viscnt 변수가 n에 도달하지 못했다면,
105+
이는 인접하지 않은 구역이 있는 것이므로
106+
인구 차이를 계산하지 않고 다음 경우로 넘어간다.
107+
108+
이같이 계산된 최솟값을 답으로 출력한다.
109+
만약, 모든 경우에 대해 선거구가 나눠지지 않는다면
110+
ans은 갱신되지 않아 INF이므로, 이 경우 -1을 출력한다.
111+
*/

0 commit comments

Comments
 (0)
0