没有上司的舞会(树上dp)
作者:互联网
P1352 没有上司的舞会 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
- f[i][1],f[i][0]分别代表第i个人去或不去的结果
- 邻接表存储直接上司下属关系
- vis[i]=1代表第i个人是下属,那么不能从他开始向下递归,(他不是根结点)
- dfs中先为f赋初值,再遍历他所有的下属,先递归进入下属,这样在内部递归会计算完他的下属的f值,在回溯的时候更新当前点的f值
- 最终答案为根节点去和不去之中的最大值
// https://www.luogu.com.cn/problem/P1352
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
#define ll long long
#define MAX 6005
// 7
// 1
// 1
// 1
// 1
// 1
// 1
// 1
// 1 3
// 2 3
// 6 4
// 7 4
// 4 5
// 3 5
int n, w[MAX], vis[MAX], f[MAX][2];
vector<int> son[MAX];
void input()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
scanf("%d", w + i);
}
for (int i = 1; i <= n - 1; i++)
{
int a, b;
scanf("%d%d", &a, &b);
son[b].push_back(a);
vis[a] = 1;
}
}
void dfs(int now)
{
f[now][1] = w[now];
f[now][0] = 0;
for (int i = 0; i < son[now].size(); i++)
{
int to = son[now][i];
dfs(to);
f[now][0] += max(f[to][0], f[to][1]);
f[now][1] += f[to][0];
}
}
int main()
{
input();
int root;
for (int i = 1; i <= n; i++)
{
if (!vis[i])
{
root = i;
break;
}
}
dfs(root);
printf("%d", max(f[root][0], f[root][1]));
}
标签:舞会,上司,cn,递归,int,MAX,下属,dp 来源: https://www.cnblogs.com/Wang-Xianyi/p/16581112.html