状态表示:
$f[u][1]$表示以u
为根节点的子树并且包括u的总快乐指数,
$f[u][0]$表示以u
为根节点并且不包括u的总快乐指数;
状态计算:
要想求得一棵以u
为根节点的子树的最大指数分为两种:选u
节点或不选u
节点
记点u的子节点是j
1.选u
,$f[u][1] += Σf[j][0]$
2.不选u
,$f[u][0] += Σmax(f[j][1] , f[j][0])$
记根节点为root
从root
开始dfs
一遍即可
最后输出$max(f[root][1] , f[root][0])$
C++ 代码
#include <iostream>
#include <cstring>
using namespace std;
const int N = 6010;
int e[N] , ne[N] , h[N] , idx;
int happy[N];
int n;
bool has_fa[N];
int f[N][2];
void add(int a , int b)
{
e[idx] = b , ne[idx] = h[a] , h[a] = idx++;
}
void dfs(int u)
{
f[u][1] = happy[u];
for(int i = h[u] ; ~i ; i = ne[i])
{
int j = e[i];
dfs(j);
f[u][1] += f[j][0];
f[u][0] += max(f[j][0] , f[j][1]);
}
}
int main()
{
cin >> n;
for(int i = 1 ; i <= n ; i++) cin >> happy[i];
memset(h , -1 , sizeof h);
for(int i = 0 ; i < n - 1 ; i++)
{
int a ,b;
cin >> b >> a;
has_fa[b] = true;
add(a , b);
}
int root = 1;
while (has_fa[root]) root ++ ;
dfs(root);
printf("%d\n", max(f[root][0], f[root][1]));
return 0;
}
请问一下,为什么用数组h[N],h[a]来表示头结点
h是head的意思,我不知道你是不是想问这个
为什么用数组h[N[来表示,单链表只用了head,是因为这个是树?才用数组来表示头结点吗?
是的
感谢
兄弟,我又来问你问题了,别觉得我烦哦hh~
为什么要做这一步,直接从1开始dfs不行吗
因为没有说根节点就是1,所以通过找没有父节点的点来确定根节点。
有问题就问,加油💪,最近AcWing用的少,有时候可能会回复不及时。
谢谢兄弟,我会努力的,你也加油💪,以后可能还要麻烦你哦hh~
请问下,将图建为无向图,保证各个点的连通性,能否实现从任一点进行 dfs 呢?
不可以,这个题需要明确找出根节点,因为每个点的状态需要依赖严格意义上的父节点,不能随便确立父子关系。