关键字:树形动态规划 类型:普通试题 问题描述
有一棵 n 个节点的树,树上每个节点都有一个正整数权值。如果一个点被选择了,那么在树上和它相邻的点都不能被选择。求选出的点的权值和最大是多少 输入格式
第一行包含一个整数 n 。
接下来的一行包含 n 个正整数,第 i 个正整数代表点 i 的权值。
接下来一共 n-1 行,每行描述树上的一条边。 输出格式
输出一个整数,代表选出的点的权值和的最大值。 样例输入 5 1 2 3 4 5 1 2 1 3 2 4 2 5 样例输出 12 样例说明
选择3、4、5号点,权值和为 3+4+5 = 12 。 数据规模与约定
对于20%的数据, n <= 20。
对于50%的数据, n <= 1000。 对于100%的数据, n <= 100000。 权值均为不超过1000的正整数。 本题的Java参考代码如下: import .*; import .*;
public class Main {
final static int MAX_N = 100010; xt) { int v = E[i].v; if (vis[v]) continue; Ed = true; sta[top++] = v; vis[v] = true;
}
if (Ed) continue; --top;
for (int i = head[u]; i + 1 != 0; i = E[i].nxt) { int v = E[i].v;
dp[v][0] += (dp[u][0], dp[u][1]); dp[v][1] += dp[u][0];
}
}
}
void run() throws IOException { }
int n = ();
for (int i = 1; i <= n; ++i)
dp[i][1] = ();
(head, -1);
for (int i = 1; i < n; ++i) { }
dfs(1, -1);
int ans = (dp[1][0], dp[1][1]); (ans); ();
int u = (); int v = (); add(u, v); add(v, u);
public static void main(String[] args) throws IOException { }
new Main().run();
Main() { ;
cin = new InputReader;
import .*; class Main {
static int n,m;
static int[] u;
static int[] v; static int[] w; static int[] d; static int[] first; static int[] next;
static Queue
public static void main(String[] args) throws IOException {
int i;
BufferedReader bfr=new BufferedReader(new InputStreamReader); String str = (); String[] s = (\ n=(s[0]); m=(s[1]); n++; m++;
u=new int[m];
v=new int[m]; w=new int[m]; first=new int[n]; next=new int[m]; d=new int[n];
inq=new boolean[n];
for(i=1;i first[i]=-1; for(i=1;i str = (); s = (\ u[i]=(s[0]); v[i]=(s[1]); w[i]=(s[2]); next[i]=first[u[i]]; first[u[i]]=i; } spfa(1); for(i=2;i } public static void spfa(int s) { int i,x; for(i=2;i d[i]=; (s); while(!()) { x=(); inq[x]=false; for(i=first[x];i!=-1;i=next[i]) if(d[v[i]]>d[x]+w[i]) {