POJ 2342 (树dp)

来源:互联网 发布:html引导页源码 编辑:程序博客网 时间:2024/06/13 16:59

题意:

一个公司要开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;}
0 0
原创粉丝点击