Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 문자열
- 시뮬레이션
- 트리
- XR Interaction Toolkit
- 유니티
- 스택
- BFS
- c++
- Unreal Engine 5
- 백준
- 정렬
- 구현
- DFS
- 자료구조
- 수학
- 알고리즘
- 그리디 알고리즘
- VR
- 다익스트라
- 유니온 파인드
- 그래프
- 백트래킹
- 투 포인터
- 다이나믹 프로그래밍
- Team Fortress 2
- 누적 합
- 재귀
- 브루트포스
- 우선순위 큐
- ue5
Archives
- Today
- Total
1일1알
백준 17471번 게리맨더링 C++ 본문
1. 한 구역에서 구역으로 갈 수 있는지 확인할 수 있는 2차원 배열을 만든다.
2. 백트래킹으로 구역을 나누는 경우를 모두 찾는다.
3. 두개의 선거구가 있을텐데, 선거구의 구역들이 다 이어져있는지 확인한다.
4. 구역들이 이어져있지만 다른 선거구가 끼어있는 경우를 걸러준다.
5. 두 선거구의 인구 차를 구하면서 최솟값을 찾는다.
골드4문제인데 골드4보단 어려웠던 것 같다.
#include <iostream>
#include <string>
#include <vector>
#include <math.h>
#include <algorithm>
#include <utility>
#include <stack>
#include <queue>
#include <math.h>
#include <set>
#include <map>
#include <list>
#include <unordered_map>
#include <unordered_set>
#include <iomanip>
#include <limits.h>
#define OUT
using namespace std;
using int64 = long long;
int n;
int sum = 0;
int ans = 987654321;
vector<int> population;
vector<bool> visited;
vector<vector<bool>> CanGo;
vector<vector<int>> graph;
void RefreshVisited() {
for (int i = 1; i <= n; i++)
visited[i] = false;
}
void Dfs(int city, int start, vector<vector<bool>>& canGo) {
visited[city] = true;
canGo[start][city] = true;
for (auto next : graph[city]) {
if (visited[next]) continue;
Dfs(next, start, canGo);
}
}
vector<bool> visited_BT;
set<int> s;
set<int> otherSet;
void BT(int idx) {
if (s.size() >= 1 && s.size() < n) {
bool connected = true;
int begin = *s.begin();
for (auto a : s) {
if (!CanGo[begin][a]) connected = false;
}
begin = *otherSet.begin();
for (auto a : otherSet) {
if (!CanGo[begin][a]) connected = false;
}
if (connected) {
vector<vector<bool>> _canGo(n + 1, vector<bool>(n + 1, false));
RefreshVisited();
for (auto a : s) {
visited[a] = true;
}
Dfs(begin, begin, _canGo);
for (auto a : otherSet) {
if (!_canGo[begin][a]) connected = false;
}
_canGo = vector<vector<bool>>(n + 1, vector<bool>(n + 1, false));
RefreshVisited();
for (auto a : otherSet) {
visited[a] = true;
}
int begin = *s.begin();
Dfs(begin, begin, _canGo);
for (auto a : s) {
if (!_canGo[begin][a]) connected = false;
}
if (connected) {
int currSum = 0;
for (auto a : s) {
currSum += population[a];
}
int otherSum = sum - currSum;
int gap = abs(currSum - otherSum);
ans = min(ans, gap);
}
}
}
for (int i = idx; i <= n; i++) {
if (visited_BT[i]) continue;
visited_BT[i] = true;
s.insert(i);
otherSet.erase(i);
BT(i + 1);
visited_BT[i] = false;
s.erase(i);
otherSet.insert(i);
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n;
population = vector<int>(n + 1);
visited = vector<bool>(n + 1, false);
visited_BT = vector<bool>(n + 1, false);
CanGo = vector<vector<bool>>(n + 1, vector<bool>(n + 1, false));
graph = vector<vector<int>>(n + 1, vector<int>());
for (int i = 1; i <= n; i++) {
cin >> population[i];
sum += population[i];
otherSet.insert(i);
}
for (int i = 1; i <= n; i++) {
int cnt;
cin >> cnt;
for (int j = 0; j < cnt; j++) {
int city;
cin >> city;
graph[i].push_back(city);
}
}
for (int i = 1; i <= n; i++) {
RefreshVisited();
Dfs(i, i, CanGo);
}
BT(1);
if (ans == 987654321) cout << -1;
else cout << ans;
}
'알고리즘' 카테고리의 다른 글
백준 2661번 좋은수열 C++ (0) | 2022.08.22 |
---|---|
백준 4179번 불! C++ (0) | 2022.08.21 |
백준 2458번 키 순서 C++ (0) | 2022.08.19 |
백준 5427번 불 C++ (0) | 2022.08.18 |
백준 1062번 가르침 C++ (0) | 2022.08.17 |