CodeForces - 1153D Serval and Rooted Tree(树形dp)

题目链接

题目大意

  给你一棵以1为根的树,你可以在叶子结点放1-叶子结点数量的数字,每个数字只能用一次,父节点有的对子节点取min,有的取max,问根结点的最大值。

解题思路

  考虑最下层的父节点,如果是max,那么在所有子节点中选一个放比较大的数,其他放比较小的数就行了,如果是min,那么就要放一连串比较大的数结果才比较大。然后再往上考虑,发现max就是取所有子节点包含的最少的结点数那一个量,而min则是将所有子节点包含的数量相加(这里的数量指的是取min和max之后的数量,不是树中的数量)。

代码

const int maxn = 3e5+10;
const int maxm = 2e3+10;
int n, cnt, state[maxn];
vector<int> e[maxn];
int dfs(int u) {
	if (e[u].empty()) {
		++cnt;
		return 1;
	}
	if (state[u]) {
		int minn = INF;
		for (auto v : e[u]) minn = min(minn, dfs(v));
		return minn;
	}
	else {
		int sum = 0;
		for (auto v : e[u]) sum += dfs(v);
		return sum;
	}
}
int main() {
	cin >> n;
	for (int i = 1; i<=n; ++i) cin >> state[i];
	for (int i = 2, a; i<=n; ++i) {
		cin >> a;
		e[a].push_back(i);
	}
	int ans = dfs(1);
	cout << cnt-ans+1 << endl;
	return 0;	
}

posted @ 2021-02-18 10:44  shuitiangong  阅读(68)  评论(0编辑  收藏  举报