ps

[백준] 1949 - 우수 마을

kariskan 2022. 8. 4. 21:20

https://www.acmicpc.net/problem/1949

 

1949번: 우수 마을

첫째 줄에 정수 N이 주어진다. (1 ≤ N ≤ 10,000) 둘째 줄에는 마을 주민 수를 나타내는 N개의 자연수가 빈칸을 사이에 두고 주어진다. 1번 마을부터 N번 마을까지 순서대로 주어지며, 주민 수는 10,00

www.acmicpc.net

 

다음과 같이 dp배열을 정의하면 거의 끝난다.

dp[i][j]는,

j가 0이면 해당 마을을 우수마을로 선정하지 않았을 때, 서브트리의 최대 우수 마을 주민 수 합

j가 1이면 해당 마을을 우수마을로 선정하였을 때, 서브트리의 최대 우수 마을 주민 수 합

 

그래서 일반 마을은 적어도 하나의 우수 마을과 인접해야 하므로 

하위 서브트리의 j가 0일때와 1일때를 각각 구해 조건에 맞게 답을 구하면 된다.

 

#include <iostream>
#include <vector>
using namespace std;

int n;
vector<vector<int>> v;
int num[10001], dp[10001][2];
int ans;

int dfs(int node, int pre, int g) {
	if (dp[node][g])return dp[node][g];

	int ret = 0;
	if (cnt)ret = num[node];

	for (auto& i : v[node]) {

		if (i != pre) {
			int no = dfs(i, node, 0);
			int yes = dfs(i, node, 1);
			if (g == 1) {
				ret += no;
			}
			else {
				ret += max(no, yes);
			}
		}
	}

	return dp[node][g] = ret;
}

int main() {

	cin >> n;
	v.resize(n + 1);
    
	for (int i = 1; i <= n; i++) {
		cin >> num[i];
	}

	for (int i = 1; i < n; i++) {
		int a, b; cin >> a >> b;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	
	cout << max(dfs(1, 0, 0), dfs(1, 0, 1));
}