285. 没有上司的舞会

题目链接

285. 没有上司的舞会

Ural 大学有 \(N\) 名职员,编号为 \(1∼N\)

他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。

每个职员有一个快乐指数,用整数 \(H_i\) 给出,其中 \(1≤i≤N\)

现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。

在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。

输入格式

第一行一个整数 \(N\)

接下来 \(N\) 行,第 \(i\) 行表示 \(i\) 号职员的快乐指数 \(H_i\)

接下来 \(N−1\) 行,每行输入一对整数 \(L,K\),表示 \(K\)\(L\) 的直接上司。

输出格式

输出最大的快乐指数。

数据范围

\(1≤N≤6000,\)
\(−128≤H_i≤127\)

输入样例:

7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5

输出样例:

5

解题思路

树形dp

  • 状态表示:

    • \(f[i][0]\) 表示不选 节点 \(i\) 的这棵子树下的最大权值
    • \(f[i][1]\) 表示选 节点 \(i\) 的这棵子树下的最大权值
  • 状态计算:

    • \(f[i][0]+=max(f[j][0],f[j][1])\),其中 \(j\)\(i\) 的儿子节点
    • \(f[i][1]=h[i],f[i][1]+=f[j][0]\)

分析:对于一棵子树的根节点来说可选可不选,注意dfs的写法

  • 时间复杂度:\(O(n+m)\)

代码

// Problem: 没有上司的舞会
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/287/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=6005;
int f[N][2],n,h[N];
vector<int> adj[N];
bool st[N];
void dfs(int x)
{
	f[x][1]=h[x];
	for(int y:adj[x])
	{
		dfs(y);
		f[x][0]+=max(f[y][0],f[y][1]);
		f[x][1]+=f[y][0];
	}
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)cin>>h[i];
    for(int i=1;i<n;i++)
    {
    	int x,y;
    	cin>>x>>y;
    	adj[y].pb(x);
    	st[x]=true;
    }
	int root=1;
	while(st[root])root++;
	dfs(root);
	cout<<max(f[root][0],f[root][1]);
    return 0;
}
posted @ 2022-02-28 20:26  zyy2001  阅读(39)  评论(0编辑  收藏  举报