POJ 2342 树形dp

版权声明:欢迎转载,不要求署名~~~ https://blog.csdn.net/shadandeajian/article/details/82995034

题目:传送门

题意:

给一棵树,每个结点都有一个权值,父节点和子节点不能同时出现,求权值和最大值是多少。

题解:

我们要在树上跑个dp,因为问题的模型只有用和不用,所以我们在树上跑01背包那个模型就行了

AC代码:

#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int dp[6005][2],val[6005],index_v[6005],vis[6005];
vector<int>adj[6005];
void dfs(int u) {
    vis[u]=true;
    dp[u][0]=0;//不用这个结点
    dp[u][1]=val[u];//用这个结点
    for(int i=0; i<adj[u].size(); i++) {
        int v=adj[u][i];
        if(vis[v])
            continue;
        dfs(v);
        dp[u][0]+=max(dp[v][0],dp[v][1]);
        dp[u][1]+=dp[v][0];
    }
}
int main(void) {
    int n,u,v;
    cin>>n;
    for(int i=1; i<=n; i++) {
        cin>>val[i];
    }
    while(cin>>v>>u&&u+v) {
        adj[u].push_back(v);
        index_v[v]++;
    }
    for(int i=1; i<=n; i++) {
        if(!index_v[i]) {
            dfs(i);//dfs搜索整棵树
            cout<<max(dp[i][0],dp[i][1]);
            return 0;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/shadandeajian/article/details/82995034