HDU 1520:Anniversary party 树形DP基础

Anniversary party

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1520

题意:

公司里有一堆人再开派对,每个人有一个欢乐值,这些人之间有一些上下级关系,每个人都不想和他的直接上司(即是父亲,不包括祖先)同时出现在party上,求party上最大的欢乐值的合。

题解:

由题意知公司成员之间可以组成一些关系树,设value[x]为以x为根节点的子树的最大权值合,child[x]为x的子节点,从树上可以看出,value[x]=max(value[x]+∑value[child[child[x]]],∑value[child[x]])

             

代码

#include<stdio.h>
#include<vector>
using namespace std;
const int N=6001;
vector<int>q[N];
int value[N];
bool in[N],mark[N];
int mmax(int x,int y)
{
  return x>y?x:y;
}
int dfs(int x)
{
  if(mark[x])return value[x];
  int v=0,w=0,t;
  for(int i=0;i<q[x].size();++i)
  {
    t=q[x][i];
    v+=dfs(t);
    for(int j=0;j<q[t].size();++j)
      w+=dfs(q[t][j]);
  }
  value[x]=mmax(value[x]+w,v);
  mark[x]=true;
  return value[x];
}
int main()
{
  int n,res,x,y;
  while(~scanf("%d",&n))
  {
    for(int i=1;i<=n;++i)
    {
      scanf("%d",&value[i]);
      q[i].clear();
      in[i]=mark[i]=false;
    }
    while(~scanf("%d%d",&x,&y)&&x&&y)
    {
    q[y].push_back(x);
    in[x]=true;
    }
    res=0;
    for(int i=1;i<=n;++i)
      if(!in[i])res+=dfs(i);
    printf("%d ",res);
  }
}

  

原文地址:https://www.cnblogs.com/kiuhghcsc/p/5592028.html