BIT1018 没有上司的聚会

来源:互联网 发布:医疗器械软件变更注册 编辑:程序博客网 时间:2024/04/30 01:42
d[i][0]表示不选该节点的以该节点为子树的最大欢乐值

d[i][1]表示选择该节点的以该节点为子树的最大欢乐值

staff表示员工

状态转移为

d[i][0]=sum(max(d[i-child][0],d[i-child][1]))
d[i][1]=sum(d[i-child][0])

#include<iostream>#include<algorithm>#include<cstdio>#include<list>using namespace std;class node{public:int happy;//快乐指数bool haveFather;//有没有父节点list<int>child;void init(){scanf("%d",&happy);haveFather=false;child.clear();}void addChild(int theChild){child.push_back(theChild);}}staff[100010];int d[100010][2];//d[i][0]表示不选该节点的以该节点为子树的最大欢乐值//d[i][1]表示选择该节点的以该节点为子树的最大欢乐值void dp(int i,int type)//求d[i][type]{if(type==0)//不选此节点,d[i][0]=sum(max(d[i-child][0],d[i-child][1])       ){d[i][0]=0;for (list<int>::iterator index=staff[i].child.begin();index!=staff[i].child.end();index++){if (d[*index][0]==-1){dp(*index,0);}if (d[*index][1]==-1){dp(*index,1);}d[i][0]+=d[*index][0]>d[*index][1]?d[*index][0]:d[*index][1];}}else//选择此节点,d[i][1]=sum (d[i-child][0]){d[i][1]=staff[i].happy;for (list<int>::iterator index=staff[i].child.begin();index!=staff[i].child.end();index++){if (d[*index][0]==-1){dp(*index,0);}d[i][1]+=d[*index][0];}}}int main(){//freopen("in.txt","r",stdin);int n;while (~scanf("%d",&n)){for(int i=1;i<=n;i++){staff[i].init();}for (int i = 0; i < n-1; i++){int l,k;scanf("%d %d",&l,&k);staff[l].haveFather=true;staff[k].addChild(l);}memset(d,-1,sizeof(d));//初始化完毕int ans=0;for(int i=1;i<=n;i++){if(staff[i].haveFather==false)//该节点为根节点,没有父亲节点{dp(i,0);dp(i,1);ans+=d[i][0]>d[i][1]?d[i][0]:d[i][1];}}printf("%d\n",ans);}return 0;}


原创粉丝点击