题目链接:https://www.acwing.com/problem/content/287/
题意:
Ural大学有N名职员,编号为。
他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。
每个职员有一个快乐指数,用整数 给出,其中 。
现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。
在满足这个条件的前提下,主办方希望邀请一部分职员参会,使得所有参会职员的快乐指数总和最大,求这个最大值。
输入格式
第一行一个整数。
接下来行,第行表示 号职员的快乐指数 。
接下来行,每行输入一对整数,表示是的直接上司。
最后一行输入0,0。
输出格式
输出最大的快乐指数。
数据范围
题解:
f[x][0]表示从以x为根的子树邀请一部分职员参会,并且x不参加舞会时,快乐指数总和的最大值。此时,x的所有子节点(直接下属)可以参会,也可以不参会。
f[x][1]表示从以x为根的子树邀请一部分职员参会,并且x参加舞会时,快乐指数总和的最大值。此时,x的所有子节点(直接下属)都不能参会。
我们先找到没有上司的节点作为根,目标为,时间复杂度为。
简单附代码:
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define Pair pair<int,int>
#define int long long
#define fir first
#define sec second
namespace fastIO{
#define BUF_SIZE 100000
#define OUT_SIZE 100000
//fread->read
bool IOerror=0;
// inline char nc(){char ch=getchar();if(ch==-1)IOerror=1;return ch;}
inline char nc(){
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if(p1==pend){
p1=buf;pend=buf+fread(buf,1,BUF_SIZE,stdin);
if(pend==p1){IOerror=1;return -1;}
}
return *p1++;
}
inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
template<class T> inline bool read(T &x){
bool sign=0;char ch=nc();x=0;
for(;blank(ch);ch=nc());
if(IOerror)return false;
if(ch=='-')sign=1,ch=nc();
for(;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if(sign)x=-x;
return true;
}
inline bool read(double &x){
bool sign=0;char ch=nc();x=0;
for(;blank(ch);ch=nc());
if(IOerror)return false;
if(ch=='-')sign=1,ch=nc();
for(;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if(ch=='.'){
double tmp=1; ch=nc();
for(;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
}
if(sign)x=-x;
return true;
}
inline bool read(char *s){
char ch=nc();
for(;blank(ch);ch=nc());
if(IOerror)return false;
for(;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
*s=0;
return true;
}
inline bool read(char &c){
for(c=nc();blank(c);c=nc());
if(IOerror){c=-1;return false;}
return true;
}
template<class T,class... U>bool read(T& h,U&... t){return read(h)&&read(t...);}
#undef OUT_SIZE
#undef BUF_SIZE
};using namespace fastIO;using namespace std;
const int N=1e6+5;
const int mod=1e9+7;
int h[N];
bool v[N];
vector<int>son[N];
int f[N][2];
void dp(int x){
f[x][0]=0;
f[x][1]=h[x];
for(int i=0;i<son[x].size();i++){
int y=son[x][i];
dp(y);
f[x][0]+=max(f[y][0],f[y][1]);
f[x][1]+=f[y][0];
}
}
signed main(){
//printf("%lld\n",112233+142536+445566+415263);
int n;read(n);
for(int i=1;i<=n;i++)read(h[i]);
for(int i=1;i<n;i++){
int x,y;read(x,y);
v[x]=1;
son[y].push_back(x);
}
int a,b;read(a,b);
int root;
for(int i=1;i<=n;i++){
if(!v[i]){root=i;break;}
}
dp(root);
printf("%lld\n",max(f[root][0],f[root][1]));
return 0;
}