src: http://acm.hdu.edu.cn/showproblem.php?pid=2196
解答:https://blog.csdn.net/shuangde800/article/details/9732825
dfs2中,用父节点的dp最大值或次大值来规划子节点的各状态的值!!! 其他题目中,一般是用子结点的值太规划父节点的各状态的值~~~位于父节点的栈中进行dp还是位于子节点的栈中进行dp具体分析~~~
ac代码:
#include <iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<functional> #include<utility> #include<string> #include<string.h> #include<vector> #include<iomanip> #include<stack> using namespace std; #define FOR(i,a,b) for(int i=a;i<=b;i++) const int inf=99999999; int n,vis[10005],Enum=0,head[10005]; long long dp[10005][2]; struct { int to,v,ne; }edge[10005]; void init(){memset(vis,0,sizeof(0));Enum=0;memset(head,-1,sizeof(head));} void add_edge(int a,int b,int v) { edge[Enum].to=b;edge[Enum].v=v; edge[Enum].ne=head[a]; head[a]=Enum++; } void dfs1(int u) { dp[u][0]=0; for(int i=head[u];i!=-1;i=edge[i].ne){ int to=edge[i].to; int v=edge[i].v; dfs1(to); dp[u][0]=max(dp[u][0],dp[to][0]+v); } } void dfs2(int u) { int max1=0,v1=-1,max2=0,v2; for(int i=head[u];i!=-1;i=edge[i].ne){ int to=edge[i].to,v=edge[i].v; int tmp=dp[to][0]+v; if(tmp>max1){ max2=max1;v2=v1;max1=tmp;v1=to; }else if(tmp==max1||tmp>max2){ max2=tmp;v2=to; } } if(u!=1){ int tmp=dp[u][1]; if(tmp>max1){ max2=max1;v2=v1;max1=tmp;v1=-1; } else if(tmp==max1||tmp>max2){max2=tmp;v2=-1;} } for(int i=head[u];i!=-1;i=edge[i].ne){ int to=edge[i].to,v=edge[i].v; //cerr<<"u is:"<<u<<" "<<max1<<' '<<max2<<endl; //system("pause");// if(to==v1){ dp[to][1]=max2+v; } else dp[to][1]=max1+v; //cerr<<"to:"<<to<<" "<<dp[to][1]<<endl;// dfs2(to); } } int main() { std::ios::sync_with_stdio(false); int b,v; while(cin>>n){ init(); for(int i=2;i<=n;i++){ cin>>b>>v; add_edge(b,i,v); } dfs1(1); // cout<<endl; // FOR(i,1,n)cout<<dp[i][0]<<' '<<dp[i][1]<<endl;// // system("pause"); dfs2(1); FOR(i,1,n){ //cout<<dp[i][0]<<' '<<dp[i][1]<<endl; cout<<max(dp[i][0],dp[i][1])<<endl; } } return 0; } /* 7 5 10 10 8 20 9 2 2 1 3 1 4 2 5 2 6 3 7 3 0 0 */