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; }