树形DP

树形dp的模板是在做题中总结出来的

POJ 2342 Anniversary party_边

树形DP满足自下而上,在dfs处通过递归实现
与scnuoj不一样,这题需要找根节点

#include 
#include 
#include 
#include 
#define maxi 6010
using namespace std;
int n,dp[maxi][2],book[maxi];
vector  G[maxi];

void dfs(int u){
    for(int i=0;i>n;
    int a,b;
    for(int i=1;i<=n;i++){
        cin>>dp[i][1];
    }
    for(int i=1;i>a>>b;
        G[b].push_back(a);
        book[a]=1;//寻找根节点
    }
    cin>>a>>b;
    int root;
    for(int i=1;i<=n;i++){
        if(!book[i]){
            root=i;
            break;
        }
    }

    dfs(root);
    cout<

 

洛谷 P2016 战略游戏_边

#include 
#include 
#include 
#include 
#define maxi 6010
using namespace std;
int n,dp[maxi][2],book[maxi];
vector  G[maxi];

void dfs(int u){
    dp[u][1]=1;
    for(int i=0;i>n;
    int a,b,c;
    int root;
    for(int i=1;i<=n;i++){
        cin>>a>>b;

        for(int j=0;j>c;
            G[a].push_back(c);
            book[c]=1;
        }
    }
    //i从0开始,自行看题
    for(int i=0;i

 

POJ 3659 Cell Phone Network_结点

//#include 
#define maxi 100010 
#define INF 99999999
using namespace std;
//dp[i][0] 自己不选,选父亲
//dp[i][1] 自己不选,选儿子
//dp[i][2] 选自己 
vector G[maxi];
int dp[maxi][3];

void dfs(int u,int f){
    dp[u][0]=0;
    dp[u][1]=0;
    dp[u][2]=1;
    if(G[u].size()==1&&G[u][0]==f){
        //到底了 
        dp[u][1]=INF;
        return ;
    }
    int flag=0,minn=INF,son=0,v;
    for(int i=0;idp[v][2]){
                minn=dp[v][2];
                son=dp[v][1];
            }
        }
        else{
            flag=1;
            dp[u][1]+=dp[v][2];
        }
    }
    if(!flag)
        dp[u][1]+=minn-son; 
} 

int main(){
    int n;
    cin>>n;
    int a,b;
    for(int i=1;i>a>>b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    dfs(1,-1);
    cout<

 

ZOJ 3201 Tree of Tree_树上DP

#include 
#include 
#include 
#include 
#include 
//#include 
#define maxi 110 
#define INF 99999999
using namespace std;

vector G[maxi];
int dp[maxi][maxi],w[maxi],k,vis[maxi];

void dfs(int u,int f){
    dp[u][1]=w[u];
    for(int i=0;i=1;j--)
            for(int l=1;l<=j;l++)
                dp[u][j]=max(dp[u][j],dp[u][l]+dp[v][j-l]);
    }
} 

int main(){
//  freopen("data","r",stdin);
    int n;
    while(scanf("%d%d",&n,&k)!=EOF){
        memset(dp,0,sizeof(dp));
        for(int i=0;i>w[i];  
        }
        int a,b;
        for(int i=0;i>a>>b;
            G[a].push_back(b);
            G[b].push_back(a);
        }

        dfs(0,-1);
        int res=0;
        for(int i=0;i

 

洛谷 P2014 选课_线上DP

#include 
#include 
#include 
#include 
#include 
//#include 
#define maxi 350 
#define INF 99999999
using namespace std;

vector G[maxi];
int dp[maxi][maxi],k,n,m,w[maxi];

void dfs(int u){
    for(int i=1;i=1;j--)
            for(int l=1;l<=j;l++)
                dp[u][j]=max(dp[u][j],dp[u][l]+dp[v][j-l]);
    }
} 

int main(){
//  freopen("data","r",stdin);
         scanf("%d%d",&n,&m);
        int a,b;
        for(int i=1;i<=n;i++){
            cin>>a>>w[i];
            G[a].push_back(i);
        }
        dfs(0);
        cout<

你可能感兴趣的:(树形DP)