AcWing 285. 图的邻接表存储+树状dp
原题链接
简单
作者:
W.W
,
2021-04-02 21:29:28
,
所有人可见
,
阅读 426
#include<bits/stdc++.h>
using namespace std;
const int N = 6010;
int happy[N];
int n;
int f[N][2]; //两个状态,f[i][0]表示以该节点为根,不包含当前结点的最大快乐值。同样的,f[i][1]表示包含当前结点的最大快乐值
//图的邻接表存储
// h 表示头结点的下标 ,以题目中的下标为索引,其值为该节点指向的第一个结点的idx下标
// e[i] 表示节点i的值(在题目中的下标)
// ne[i] 表示节点i的next指针是多少
// idx 存储当前已经用到了哪个点(数组自己的下标,自建索引)
int h[N], e[N], ne[N], idx;
bool has_father[N];
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!=-1; i = ne[i]) //此时i为idx索引
{
int j = e[i]; //j为题目中的下标
dfs(j);
f[u][0] += max(f[j][0], f[j][1]);
f[u][1] += f[j][0];
}
}
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
{
cin>>happy[i];
}
memset(h, -1, sizeof h);
for(int i=1; i<=n-1; i++) //n-1条边
{
int a, b;
cin>>a>>b;
add(b,a);
has_father[a] = true;
}
//找根结点
int root=1;
while(has_father[root]) root++;
dfs(root);
// for(int i=1; i<=n; i++)
// printf("%d:f[i][0]:%d, f[i][1]: %d\n",i, f[i][0],f[i][1]);
printf("%d\n", max(f[root][0],f[root][1]));
return 0;
}
写的很棒。