AcWing 285. 简单注释
原题链接
简单
作者:
季之秋
,
2021-02-19 22:17:38
,
所有人可见
,
阅读 281
/*
拉链法连接边 没有父节点的就是根节点,每个根节点选中就要加上这个点的权值,
遍历根节点的子节点,递归子节点,递归到最下面就开始累计状态表示,每个点选或不选 状态计算不同
f[i][0]表示i为根节点且符合条件的树最大值,并且不选根节点,所以子节点可选可不选
f[i][1]表示选根节点,子节点只能不选,
*/
import java.util.*;
public class Main{
static int N=6010,idx=0;
static int e[]=new int[N];
static int ne[]=new int[N];
static int h[]=new int[N];
static int happy[]=new int[N];
static int f[][]=new int[N][2];
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
boolean has_feather[]=new boolean[N];
int n=sc.nextInt();
for(int i=1;i<=n;i++) f[i][1]=sc.nextInt(); //初始化,根据状态赋值,选择u点就要加上权值
Arrays.fill(h,-1);
for(int i=1;i<n;i++){ //加边,确定有没有父节点
int a=sc.nextInt();
int b=sc.nextInt();
add(b,a);
has_feather[a]=true;
}
int boot=1;
while(has_feather[boot]) boot++; //找根节点(没有父节点的点)
dfs(boot); //从根节点开始递归
System.out.println(Math.max(f[boot][0],f[boot][1])); //两种情况,选根节点或不选
}
static void add(int a,int b){
e[idx]=b;ne[idx]=h[a];h[a]=idx++; //模拟散列表(哈希表)的拉链法
}
static void dfs(int u){
for(int i=h[u];i!=-1;i=ne[i]){//遍历子节点
int j=e[i];
dfs(j); //给每个子节点f[j][1]赋值
f[u][0]+=Math.max(f[j][0],f[j][1]); //然后去累加子节点的值
f[u][1]+=f[j][0];
}
}
}