fragment-header
fragment-markdown
홈
로그인
로그아웃
내 블로그
설정
로그인
백준 1949 (C++) 우수 마을
최초 업로드: 2025-04-26 05:27:16
최근 수정 시간: 2025-07-25 09:04:32
게시자: rlatjwls3333
카테고리: 백준
조회수: 9
# [Gold II] 우수 마을 [문제 링크](https://www.acmicpc.net/problem/1949) ## 문제 설명 <p>N개의 마을로 이루어진 나라가 있다. 편의상 마을에는 1부터 N까지 번호가 붙어 있다고 하자. 이 나라는 트리(Tree) 구조로 이루어져 있다. 즉 마을과 마을 사이를 직접 잇는 N-1개의 길이 있으며, 각 길은 방향성이 없어서 A번 마을에서 B번 마을로 갈 수 있다면 B번 마을에서 A번 마을로 갈 수 있다. 또, 모든 마을은 연결되어 있다. 두 마을 사이에 직접 잇는 길이 있을 때, 두 마을이 인접해 있다고 한다.</p> <p>이 나라의 주민들에게 성취감을 높여 주기 위해, 다음 세 가지 조건을 만족하면서 N개의 마을 중 몇 개의 마을을 '우수 마을'로 선정하려고 한다.</p> <ol> <li>'우수 마을'로 선정된 마을 주민 수의 총 합을 최대로 해야 한다.</li> <li>마을 사이의 충돌을 방지하기 위해서, 만일 두 마을이 인접해 있으면 두 마을을 모두 '우수 마을'로 선정할 수는 없다. 즉 '우수 마을'끼리는 서로 인접해 있을 수 없다.</li> <li>선정되지 못한 마을에 경각심을 불러일으키기 위해서, '우수 마을'로 선정되지 못한 마을은 적어도 하나의 '우수 마을'과는 인접해 있어야 한다.</li> </ol> <p>각 마을 주민 수와 마을 사이의 길에 대한 정보가 주어졌을 때, 주어진 조건을 만족하도록 '우수 마을'을 선정하는 프로그램을 작성하시오.</p> ## 입력 <p>첫째 줄에 정수 N이 주어진다. (1 ≤ N ≤ 10,000) 둘째 줄에는 마을 주민 수를 나타내는 N개의 자연수가 빈칸을 사이에 두고 주어진다. 1번 마을부터 N번 마을까지 순서대로 주어지며, 주민 수는 10,000 이하이다. 셋째 줄부터 N-1개 줄에 걸쳐서 인접한 두 마을의 번호가 빈칸을 사이에 두고 주어진다.</p> ## 출력 <p>첫째 줄에 '우수 마을'의 주민 수의 총 합을 출력한다.</p> ## 풀이 #### dp[i][0]를 i번 마을이 우수 마을이 아닐 때의 최대 주민 수, dp[i][1]을 i번 마을이 우수 마을일 때의 최대 주민 수로 두고 풀었다. ``` c++ #include<bits/stdc++.h> using namespace std; const int MAX = 10'000; int dp[MAX][2]; // [][우수마을X, 우수마을O] int cost[MAX]; bool visited[MAX]; vector<vector<int>> conn(MAX); void dfs(int cur) { visited[cur]=true; dp[cur][1] = cost[cur]; for(int next:conn[cur]) { if(!visited[next]) { dfs(next); dp[cur][0] += max(dp[next][0], dp[next][1]); dp[cur][1] += dp[next][0]; } } } int main() { ios::sync_with_stdio(0); cin.tie(0); int n; cin >> n; for(int i=0;i<n;i++) cin >> cost[i]; for(int i=0;i<n-1;i++) { int u, v; cin >> u >> v; conn[u-1].push_back(v-1); conn[v-1].push_back(u-1); } dfs(0); cout << max(dp[0][0], dp[0][1]); } ```