题意:
一个公司要开party,想要邀请很多人来,每一个人来都代表着有趣值,但是如果有两
人是直接上下级的关系,则不允许。求出最大funny值。
思路:
关系是以树的形式给出,适合树dp。。。那么怎么想呢?考虑这种状态,一个人去,
则其直接子节点不去,如果他去,其直接子节点可去,可不去。
好吧!其实状态已经给出了。具体看代码。
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
const int MAXN = 60005;
int n;
vector<int >G[MAXN];
int w[MAXN],dp[MAXN][2];
int dfs(int x,int s,int fa)
{
if(dp[x][s] != -1)
return dp[x][s];
dp[x][s] = 0;
if(s) {
dp[x][s] = w[x];
int size = G[x].size();
for(int i = 0;i < size; i++) {
if(G[x][i] != fa) {
dp[x][s] += dfs(G[x][i],0,x);
}
}
}
else {
int size = G[x].size();
for(int i = 0;i < size; i++) {
if(G[x][i] != fa) {
dp[x][s] += max(dfs(G[x][i],1,x),dfs(G[x][i],0,x));
}
}
}
return dp[x][s];
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d",&n) != EOF) {
memset(dp,-1,sizeof(dp));
for(int i = 1;i <= n; i++)
G[i].clear();
for(int i = 1;i <= n; i++)
scanf("%d",&w[i]);
int s,e;
while(scanf("%d%d",&s,&e) != EOF) {
if(s == 0 && e == 0)
break;
G[s].push_back(e);
G[e].push_back(s);
}
printf("%d\n",max(dfs(1,1,-1),dfs(1,0,-1)));
}
return 0;
}