树型DP

树型DP不同于普通的的DP之处在于:通过递归找出儿子的信息,在回溯的过程中DP,计算结果(似乎很像记忆化搜索。。。。。。)然后处理相关信息,回答询问》》》》》》》经典应用:点分治中求重心,树链剖分中求重儿子,等等。。。。。。。。。

给大家几道水题》》》》

http://poj.org/problem?id=2342

http://oj.changjun.com.cn/problem/detail/pid/1976

http://oj.changjun.com.cn/problem/detail/pid/1634

http://oj.changjun.com.cn/problem/detail/pid/2171

第一题原码

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXX 6000
#define INF -99999999
using namespace std;
struct data{
  int nxt,to;
}edge[MAXX*2+1];
int dp[MAXX+1][2];//1选,0不选
int head[MAXX+1],tot,ans,n;
bool vis[MAXX+1];
void add(int from,int too){edge[++tot].nxt=head[from];head[from]=tot;edge[tot].to=too;}
void dfs(int num){
  for(int i=head[num];i;i=edge[i].nxt){
      int too=edge[i].to;
      dfs(too);
      dp[num][0]+=max(dp[too][0],dp[too][1]);
      dp[num][1]+=dp[too][0];
  }
}
int main(){
  /* freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);*/
  while(scanf("%d",&n)!=EOF){
    memset(head,0,sizeof(head));
    memset(vis,false,sizeof(vis));
    for(int i=1;i<=n;++i)dp[i][0]=0;
    tot=0;
    for(int i=1;i<=n;++i)scanf("%d",&dp[i][1]);
    int a,b;while(scanf("%d%d",&a,&b)&&a!=0&&b!=0)add(b,a),vis[a]=true;
    for(int i=1;i<=n;++i)if(!vis[i]){dfs(i),printf("%d\n",max(dp[i][0],dp[i][1]));break;}
  }
  return 0;
}


posted @ 2017-02-08 21:15  QYP_2002  阅读(100)  评论(0编辑  收藏  举报