반응형
문제 출처 :
https://www.acmicpc.net/problem/1949
알고리즘 분석 :
문제 해결에 필요한 사항
1. Dynamic Programming
2. 점화식 세우는 방법
이 나라의 주민들에게 성취감을 높여 주기 위해, 다음 세 가지 조건을 만족하면서 N개의 마을 중 몇 개의 마을을 '우수 마을'로 선정하려고 한다.
- '우수 마을'로 선정된 마을 주민 수의 총 합을 최대로 해야 한다.
- 마을 사이의 충돌을 방지하기 위해서, 만일 두 마을이 인접해 있으면 두 마을을 모두 '우수 마을'로 선정할 수는 없다. 즉 '우수 마을'끼리는 서로 인접해 있을 수 없다.
- 선정되지 못한 마을에 경각심을 불러일으키기 위해서, '우수 마을'로 선정되지 못한 마을은 적어도 하나의 '우수 마을'과는 인접해 있어야 한다.
이를 토대로 만들어지는 점화식은 다음과 같다.
// 현재 마을이 1(우수 마을)이라면 다음 마을은 우수 마을이 될 수 없다.
if (i == 1)
ret += dy(next, 0);
// 현재 마을이 0(우수 마을 x)이라면
// 다음 마을은 우수 마을 or 우수 마을 x일 수 있다.
else
ret += max(dy(next, 0), cost[next] + dy(next, 1));
여기서 1, 2번은 충족하지만 3번이 충족하지 못한다.
하지만 else 부분에서 자동적으로 max를 구하기 때문에 우수 x - 우수 x - 우수 x 같은 형식은 나오지 않는다.
그리고 이전에 getTree를 통해 부모 자식관계를 명확히 설정해준다.
map은 양방향 트리
tree는 단방향 트리로 구성되어있다.
소스 코드 :
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #include <cstdio> #include <vector> #include <queue> #include <iostream> #define max(a,b)(a > b ? a : b) #define swap(a,b){int t; t = a; a = b; b = t;} typedef long long int lli; using namespace std; int cost[10003]; vector <int> map[10003]; vector <int> tree[10003]; bool visit[10003]; queue <int> q; void getTree(int start) { q.push(start); while (!q.empty()) { int here = q.front(); visit[here] = true; q.pop(); for (int i = 0; i < map[here].size(); i++) { if (!visit[map[here][i]]) { tree[here].push_back(map[here][i]); q.push(map[here][i]); } } } } lli dy(int here, int i) { lli ret = 0; for (int j = 0; j < tree[here].size(); j++) { int next = tree[here][j]; // 현재 마을이 1(우수 마을)이라면 다음 마을은 우수 마을이 될 수 없다. if (i == 1) ret += dy(next, 0); // 현재 마을이 0(우수 마을 x)이라면 // 다음 마을은 우수 마을 or 우수 마을 x일 수 있다. else ret += max(dy(next, 0), cost[next] + dy(next, 1)); } return ret; } int main() { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &cost[i]); for (int i = 1; i<n; i++) { int from, to; scanf("%d %d", &from, &to); map[from].push_back(to); map[to].push_back(from); } getTree(1); printf("%lld\n", max(dy(1, 0), cost[1] + dy(1, 1))); return 0; } // This source code Copyright belongs to Crocus // If you want to see more? click here >> | Crocus |
반응형
'Applied > 알고리즘 문제풀이' 카테고리의 다른 글
[2294번] 동전 2 (0) | 2017.03.06 |
---|---|
[13913번] 숨바꼭질 4 (2) | 2017.03.04 |
[1620번] 나는야 포켓몬 마스터 이다솜 (0) | 2017.03.03 |
[13549번] 숨바꼭질 3 (0) | 2017.02.28 |
[12851번] 숨바꼭질 2 (0) | 2017.02.28 |