zoj 2315 New Year Bonus Grant 夜

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1315

简单的树型DP   

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define ll long long

using namespace std;
const int INF=0x3f3f3f3f;
const int MOD=100000007;
const int N=500005;
int MAX[N][2],f[N];
int in[N],c[N];
int head[N],I;
vector<int>vt;
struct node
{
    int j,next;
}edge[N];
void add(int i,int j)
{
    edge[I].j=j;
    edge[I].next=head[i];
    head[i]=I++;
}
int dp(int x,int k)
{
    if(MAX[x][k]!=-1)
    return MAX[x][k];
    if(in[x]==0)
    return (MAX[x][k]=0);
    MAX[x][k]=0;
    int tmp=-INF,l=0;
    for(int t=head[x];t!=-1;t=edge[t].next)
    {
        int w=edge[t].j;
        MAX[x][k]+=(dp(w,0));
        if(dp(w,1)-dp(w,0)>tmp)
        {
            tmp=dp(w,1)-dp(w,0);
            l=w;
        }
    }
    if(k==0)
    {
        c[x]=l;
        MAX[x][k]+=(tmp+1);
    }
    return MAX[x][k];
}
void dfs(int x,int k)
{//cout<<x<<" "<<k<<endl;
    if(in[x]==0) return;
    if(k==0)
    vt.push_back(c[x]);
    for(int t=head[x];t!=-1;t=edge[t].next)
    {
        int w=edge[t].j;
        if(k==0&&c[x]==w)
        dfs(w,1);
        else
        dfs(w,0);
    }
}
int main()
{
    //freopen("data.in","r",stdin);
    int T;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        memset(in,0,sizeof(in));
        memset(head,-1,sizeof(head));I=0;
        for(int i=2;i<=n;++i)
        {cin>>f[i];++in[f[i]];add(f[i],i);}
        memset(MAX,-1,sizeof(MAX));
        cout<<(dp(1,0)*1000)<<endl;
        vt.clear();
        dfs(1,0);
        sort(vt.begin(),vt.end());
        for(unsigned int i=0;i<vt.size();++i)
        {
            if(i>0) cout<<" ";
            cout<<vt[i];
        }cout<<endl;
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/liulangye/p/3040547.html