码迷,mamicode.com
首页 > 其他好文 > 详细

[bzoj3829][Poi2014]FarmCraft_树形dp

时间:2019-10-31 21:21:28      阅读:95      评论:0      收藏:0      [点我收藏+]

标签:int   ace   排序   zoj   online   设计   poi   node   name   

FarmCraft

题目链接https://lydsy.com/JudgeOnline/problem.php?id=3829

数据范围:略。


题解

因为每条边只能必须走两次,所以我们的路径一定是进入了一棵子树然后出来,不可能再进去。

我们根据这个性质,设计出状态$f_i$表示以$i$为根的子树答案即可。

转移时,我们发现需要对儿子进行一个排序,我们就暴力的判断一下哪个儿子在前面更优即可。

代码

#include <bits/stdc++.h>

#define N 1000010 

using namespace std;

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
	int x = 0, f = 1;
	char c = nc();
	while (c < 48) {
		if (c == ‘-‘)
			f = -1;
		c = nc();
	}
	while (c > 47) {
		x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
	}
	return x * f;
}

int head[N], to[N << 1], nxt[N << 1], tot;

inline void add(int x, int y) {
	to[ ++ tot] = y;
	nxt[tot] = head[x];
	head[x] = tot;
}

int sz[N];

void dfs(int p, int fa) {
	sz[p] = 1;
	for (int i = head[p]; i; i = nxt[i]) {
		if (to[i] != fa) {
			dfs(to[i], p);
			sz[p] += sz[to[i]];
		}
	}
}

int t[N], f[N];

struct Node {
	int val, id;
}q[N];

// inline bool cmp(const Node &a, const Node &b) {
// 	return a.val < b.val;
// }

inline bool cmp(const Node &a, const Node &b) {
	return max(a.val, sz[a.id] * 2 + b.val) < max(b.val, sz[b.id] * 2 + a.val);
}

void dfs1(int p, int fa) {
	f[p] = t[p];
	for (int i = head[p]; i; i = nxt[i]) {
		if (to[i] != fa) {
			dfs1(to[i], p);
		}
	}
	int cnt = 0;
	for (int i = head[p]; i; i = nxt[i]) {
		if (to[i] != fa) {
			q[ ++ cnt] = (Node) {f[to[i]], to[i]};
		}
	}
	sort(q + 1, q + cnt + 1, cmp);
	int sum = 0;
	for (int i = 1; i <= cnt; i ++ ) {
		f[p] = max(f[p], f[q[i].id] + sum + 1);
		sum += sz[q[i].id] * 2;
	}
}

int main() {
	int n = rd();
	// int m = t[1];
	for (int i = 1; i <= n; i ++ ) {
		t[i] = rd();
	}
	// t[1] = 0;
	for (int i = 1; i < n; i ++ ) {
		int x = rd(), y = rd();
		add(x, y), add(y, x);
	}
	dfs(1, 1);
	dfs1(1, 1);
	// for (int i = 1; i <= n; i ++ ) {
	// 	printf("%d ", f[i]);
	// }
	// puts("");
	cout << max(f[1], (n - 1) * 2 + t[1]) << endl ;
	return 0;
}

 

[bzoj3829][Poi2014]FarmCraft_树形dp

标签:int   ace   排序   zoj   online   设计   poi   node   name   

原文地址:https://www.cnblogs.com/ShuraK/p/11773693.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!