树状DP入门。每组数据只有一颗树。一开始当二叉做,错了- -!一开始子节点开了1005,后来又试了105,都可以。
重写一遍,邻接表~当初的写法不忍直视。。。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define N 100005
typedef long long LL;
struct Tree{
int val;
Tree * next;
}e[N], * head[N];
int par[N];
int v[N];
int n;
int ptr;
void init(){
ptr = 0;
for(int i = 1; i <= n; i++){
par[i] = i;
}
memset(head, NULL, sizeof(head));
}
void Insert(int x, int y){
par[x] = y;
e[ptr].val = x;
e[ptr].next = head[y];
head[y] = &e[ptr++];
}
int tdp(int x){
Tree *p;
int ans0 = 0;
int ans1 = v[x];
p = head[x];
while(p != NULL){
ans0 += tdp(p -> val);
Tree *pp = head[p -> val];
while(pp != NULL){
ans1 += tdp(pp -> val);
pp = pp -> next;
}
p = p -> next;
}
return max(ans0, ans1);
}
int main(){
while(scanf("%d", &n) != EOF){
init();
for(int i = 1; i <= n; i++){
scanf("%d", &v[i]);
}
int x, y;
while(scanf("%d%d", &x, &y), x || y){
Insert(x, y);
}
int root = 0;
for(int i = 1; i <= n; i++){
if(par[i] == i)root = i;
}
printf("%d\n", tdp(root));
}
return 0;
}
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
struct Node
{
int par;
int v;
int son[105];//HDOJ数据中子节点105即可
int num;
}a[6005];
int r[6005];
int v[6005];
void init (int n)
{
for(int i=0;i<=n;i++)
{
a[i].par=i;
a[i].v=0;
a[i].num=0;
}
}
int dfs(int x)
{
if(v[x]!=0)return r[x];
if(x==0)return 0;
v[x]=1;
if(a[x].num==0){r[x]=a[x].v;return r[x];}
int i0=0,i1=a[x].v;
for(int i=0;i<a[x].num;i++)
{
i0+=dfs(a[x].son[i]);
for(int j=0;j<a[a[x].son[i]].num;j++)
{
i1+=dfs(a[a[x].son[i]].son[j]);
}
}
r[x]=max(i0,i1);
return r[x];
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(v,0,sizeof(v));
init (n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i].v);
}
int x,y,k=0;
while(scanf("%d%d",&x,&y),x||y)
{
a[x].par=y;
a[y].son[a[y].num]=x;
a[y].num++;
}
x=1;
while(a[x].par!=x)
{
x=a[x].par;
}
int ans=dfs(x);
printf("%d\n",ans);
}
return 0;
}