poj 2342 anniversary party(树形dp入门)

来源:互联网 发布:k60单片机百度百科 编辑:程序博客网 时间:2024/05/01 09:19

题目链接:点击打开链接

题目大意:给一些关系,都是上下级的关系,但是同时出现在party上就会不开心,每个人都有一个开心值,于是主板要使得party的开心值最大,则

题目分析:很裸的树形dp。很不错的模板题目。用二维的dp[ i ][ 0 ],dp[ i ][ 1 】来表示来还是不来。最后算最大的max(dp[ root ][ 0 ],dp[ root ][ 1 】 )

                    还有就是根据入度值来找根节点

题目总结:发现交c++很严格,比如有返回值的函数,就一定要写return ,否则ce


#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;const int maxn=6005;struct data{    int u,v,next;} edge[maxn];int head[maxn],dp[maxn][2],indegree[maxn],val[maxn];int num;void add_edge(int u,int v){    edge[num].u=u,edge[num].v=v,edge[num].next=head[u];head[u]=num++;}void dfs(int u){    if(head[u]==-1)    {        dp[u][0]=0;        dp[u][1]=val[u];            }   else    {   for(int i=head[u];i!=-1;i=edge[i].next)        {           int v=edge[i].v;           dfs(v);           dp[u][0]+=max(dp[v][1],dp[v][0]);           dp[u][1]+=dp[v][0];        }        dp[u][1]+=val[u];    }}int main(){      int n;    scanf("%d",&n);    memset(head,-1,sizeof(head));    memset(dp,0,sizeof(dp));    memset(indegree,0,sizeof(indegree));    for(int i=1; i<=n; i++)        scanf("%d",&val[i]);    int u,v;    num=0;    while(1)    {        scanf("%d %d",&v,&u);        if(v==0&&u==0)            break;        add_edge(u,v);        indegree[v]++;    }    int root;    for(int i=1; i<=n; i++)        if(indegree[i]==0)        {            root=i;            break;        }    dfs(root);    printf("%d\n",max(dp[root][0],dp[root][1]));    return 0;}