题目


分析
输入:
5
1 2 3 4 5
1 2
1 3
2 4
2 5
输出:
12
首先建立对应的树

依题意,不能同时选择孩子与双亲

链式向前星
struct Edge{
int next;
int to;
int w;
};
- edge[i].to:表示第i条边的终点
- edge[i].next:表示与第i条边同起点的下一条边的存储位置
- edge[i].w:表示边的权值
head[]:
加边函数:
void add(int from, int to, int w){
edge[cnt].w = w;
edge[cnt].to = to;
edge[cnt].next = head[from];
head[from] = cnt++;
}
代码
import java.util.Arrays;
import java.util.Scanner;
public class Main {
final static int max = 100010;
static class edge{
int to, next;
public edge(int to, int next) {
// TODO Auto-generated constructor stub
this.to = to;
this.next = next;
}
}
static int head[] = new int [max];
static edge e[] = new edge[2*max];
static int dp[][] = new int [max][2];
static int cnt = 0;
static void add(int from, int to) {
e[cnt] = new edge(to, head[from]);
head[from] = cnt++;
}
static void dfs(int root, int pre) {
for(int i = head[root]; i != -1; i = e[i].next) {
if(e[i].to != pre) {
dfs(e[i].to, root);
dp[root][0] += Math.max(dp[e[i].to][0], dp[e[i].to][1]);
dp[root][1] += dp[e[i].to][0];
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n;
n = sc.nextInt();
Arrays.fill(head, -1);
for(int i=0; i<n; i++) {
dp[i][1] = sc.nextInt();
}
for(int i=0; i<n-1; i++) {
int a,b;
a = sc.nextInt() - 1;
b = sc.nextInt() - 1;
add(a,b);
add(b,a);
}
dfs(0, -1);
System.out.println(Math.max(dp[0][0], dp[0][1]));
}
}
这篇博客讨论了一个图论问题,即如何找到一个节点集合,使得在这个集合中任意两个节点都不直接相连,同时最大化这个集合的节点权值之和。作者介绍了链式向前星作为图的数据结构,并给出了加边函数。随后,通过深度优先搜索实现了一个动态规划解决方案,用于计算最大点集的权值。最后,代码展示了如何读取输入、构建图并输出结果。
&spm=1001.2101.3001.5002&articleId=123027503&d=1&t=3&u=e6640aa09f8241cc914c214cddb8e06e)
680

被折叠的 条评论
为什么被折叠?



