HDU1520

The meaning of the question is that, given a tree, each point has a weight, the goal is to select some points to maximize the total weight sum, but requires that any pair of parent nodes and child nodes cannot be selected together.

Ideas: DP. The tall and noble point is the tree-shaped DP.

Going from the child node to the root node, DP[ i ][ 0 ] represents the subtree with i as the vertex, and the maximum value when the i point is not selected.
DP[ i ][ 1 ] represents the subtree with i as the vertex, and the maximum value in the case of i is selected.

From this, the following transition equation can be thought of:

dp[ i ][ 0 ] = sum{ max { dp[ j ][ 0 ], f[ j ][ 1 ] }, j is the child of i }

The meaning of this article is that when the i point is not selected, its child nodes can be selected or selected, so the maximum sum is taken for each child node selected or not.
dp[ i ][ 1 ] = val[ i ] + sum{ dp[ j ][ 0 ], j is the child of i }

This means that when point i is selected, its child node must be unselectable, so directly take the sum of all child nodes that are not selected.

The role of DFS is to achieve bottom-up. Although the surface is written from top to bottom, it is bottom-up after backtracking.

The function of the tree array is to find the root node (in fact, it is also the root node determined by the input), or it is more accurate to select a point as the root node.

#include<iostream>  
#include<cstdio>  
#include<algorithm>  
#include<vector>  
#include<queue>  
#include<cmath>  
#include<cstring>  
using namespace std;  
#define INF 0x3f3f3f3f;  
vector<int>q[10000];  
int tree[10000];  
int val[10000];  
int dp[10000][2];  
int vis[10000];  
intn,m;  
  
void dfs(int u){  
    vis [u] = true ;  
    dp[u][0] = 0;  
    dp[u][1] = val[u];  
    for(int i=0; i<q[u].size(); ++i){  
        int v = q[u][i];  
        if(vis[v]) continue;  
        dfs(v);  
        dp[u][0] += max(dp[v][1], dp[v][0]);  
        dp[u][1] += dp[v][0];  
    }  
}  
  
int main(){  
  
    while(~scanf("%d", &n) && n)
    {  
        for(int i=1; i<=n; ++i) 
            q[i].clear();    
        for(int i=1; i<=n; ++i)  
            scanf("%d", &val[i]);   
        memset(tree, 0, sizeof(tree));    
            int u, v;  
        while(~scanf("%d%d", &v, &u) && v+u)
        {  
            q[u].push_back(v);  
            ++ tree [v];  
        }    
        memset(dp, 0, sizeof(dp));  
        for(int i=1; i<=n; ++i)if(!tree[i])
        {  
            memset(vis, 0, sizeof(vis));  
            dfs(i);  
            printf("%d\n", max(dp[i][0], dp[i][1]));  
            break;  
        }  
    }  
  
    return 0;  
}  

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325026578&siteId=291194637