您的位置:首页 > 其它

[HDU] 1520 Anniversary party 入门树形DP

2013-08-07 15:52 603 查看
题目链接:

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

方法: 领导选择出现,则其直接下属不能出现,领导选择不出现,则其直接下属可出现可不出现,设F(P,0)为一个员工不出现能得的最大值,F(P,1)为一个员工要出现能得的最大值

      {

      sum({F(S,0)|S是p的直接下属})+p的有趣度;P为非叶子

F(P,1)=

      p的有趣度;P为叶子

      },

      {

      sum({ min(F(S,1),F(S,0)) |S是p的直接下属 });P为非叶子

F(P,0)=

      0;P为叶子

      }

原来问题的解是min(F(root,1),F(root,0)).

注意输入不一定是树结构,有可能是森林,所以要把所有的树都DP一次,把结果累加起来。

代码:

#include <iostream>
#include <queue>
#include<algorithm>
using namespace std;
int n,m;
struct Arc
{
int vetex;
Arc* nextArc;
};
struct Node
{
int x;
int inDegree;
Arc* firstArc;
int value;
int in;
int notIn;
};
Node nodes[6001];
int myMax(int x,int y)
{
return x>y ? x:y;
}
void DFSDP(int root)
{
Arc* arc = nodes[root].firstArc;
int sonCount=0,v;
while(arc!=NULL)
{
v=arc->vetex;
DFSDP(v);
nodes[root].in+=nodes[v].notIn;
nodes[root].notIn+=myMax(nodes[v].notIn,nodes[v].in);
arc=arc->nextArc;
sonCount++;
}
if(sonCount==0)
{
nodes[root].in=nodes[root].value;
nodes[root].notIn=0;
}
}
void createArc(int s,int e)
{
Arc* arc = (Arc*)malloc(sizeof(Arc));
arc->vetex=e;
if(nodes[s].firstArc==NULL)
arc->nextArc=NULL;
else
arc->nextArc=nodes[s].firstArc;
nodes[s].firstArc = arc;
}
void main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&nodes[i].value);
nodes[i].firstArc=NULL;
nodes[i].notIn=nodes[i].inDegree=0;
nodes[i].in=nodes[i].value;
}
int emp,boss;
while(scanf("%d %d",&emp,&boss) && !(emp==0 && boss==0))
{
nodes[boss].x = boss;
nodes[emp].x = emp;
createArc(boss,emp);
nodes[emp].inDegree++;
}
int re=0;
for(int i =1;i<=n;i++)
{
if(nodes[i].inDegree==0)
{
DFSDP(i);
re+=myMax(nodes[i].in,nodes[i].notIn);
}
}
cout<<re<<endl;
}
}


感想:模板题
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: