1. 程式人生 > >樹形dp poj-2342與codeforces Round #525(Div 2)E

樹形dp poj-2342與codeforces Round #525(Div 2)E

poj-2342

題目連結:http://poj.org/problem?id=2342

很簡單的樹形dp,狀態方程是:

dp[i][1]+=dp[j][0] (在選擇 i 的情況,j 是 i 的下屬 )

dp[i][0]+=max(dp[j][0],dp[j][1]) (在不選擇 i 的情況,i的下屬 j 可選可不選 )

ac code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
#define N 30005
struct edge {
	int v;
	struct edge* f;
};
edge* a[N];
vector<int>b[N];
int dp[N][2];
int n, root;
void trees(int edg) {
	if (b[edg].size() == 0) {
		return;
	}
	for (int i = 0; i < b[edg].size(); i++) {
		trees(b[edg][i]);
		dp[edg][1] += dp[b[edg][i]][0];
		dp[edg][0] += max(dp[b[edg][i]][0], dp[b[edg][i]][1]);
	}
}
int main() {
	int L, K;
	memset(dp, 0, sizeof(dp));
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		a[i] = new edge;
		a[i]->f = NULL;
	}
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]->v);
	}
	while (~scanf("%d%d", &L, &K) && !(L == 0 && K == 0)) {
		a[L]->f = a[K];
		b[K].push_back(L);
	}
	for (int i = 1; i <= n; i++) {
		dp[i][1] = a[i]->v;
		if (a[i]->f == NULL) {
			root = i;
		}
	}
	trees(root);
	cout << max(dp[root][1], dp[root][0]) << endl;
	return 0;
}

codeforces Round #525(Div 2)E

題目連結:http://codeforces.com/contest/1088/problem/E

題解:

ac code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<set>
#include<vector>
#include<queue>
using namespace std;
#define N 300005
long long dp[N];
int n, a[N];
long long sum = -1e9;
int k = 0;
vector<int>q[N];
void dfs(int root, int p, int l) {
	dp[root] = a[root];
	for (int i = 0; i < q[root].size(); i++) {
		if (q[root][i] != p) {
			dfs(q[root][i], root, l);
			if (dp[q[root][i]] > 0) {
				dp[root] += dp[q[root][i]];
			}
		}
	}
	if (l) {
		sum = max(sum, dp[root]);
		//cout << sum << " " << root << endl;
	}
	else {
		if (dp[root] == sum) {
            dp[root] = 0;
			k++;
		}	
	}
}
int main() {
	int u, v;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
	}
	for (int i = 1; i < n; i++) {
		scanf("%d%d", &u, &v);
		q[u].push_back(v);
		q[v].push_back(u);
	}
	dfs(1, 0, 1);
	dfs(1, 0, 0);
	printf("%I64d %d", sum*k, k);
	return 0;
}