POJ 2342 树的最大独立集

题意:在树的最大独立集的基础上,加上权值。求最大。

分析:

采用刷表的方式写记忆化,考虑一个点选和不选,返回方式pair 型。

首先,无根树转有根树,dp(root)。

注意的是:u不选,那么他的子节点,可以选,或者不选。WA了无数次。

#include <cstdio>
#include <vector>
#include <cmath>

using namespace std;

const int maxn = 6000+5;
vector<int> G[maxn];
int a[maxn];
int p[maxn];

void dfs(int u,int fa)
{
    int d = G[u].size();
    for(int i=0; i<d; i++)
    {
        int v = G[u][i];
        if(v!=fa)
            dfs(v,p[v]=u);
    }
}

int d[maxn][2];
bool vis[maxn];

void dp(int u)
{
    if(vis[u])
        return;
    vis[u] = 1;

    for(int i=0; i<G[u].size(); i++)
    {
        int v = G[u][i];
        if(v!=p[u])
        {
            dp(v);
            d[u][1] +=d[v][0];
            d[u][0] +=max(d[v][1],d[v][0]);
        }
    }
}

int main()
{
    //freopen("in.txt","r",stdin);
    int n;
    scanf("%d",&n);
    for(int i=1; i<=n; i++) {
        scanf("%d",&a[i]);
        d[i][1] = a[i];
    }

    int u,v;
    while(scanf("%d%d",&u,&v),u+v)
    {
        G[u].push_back(v);
        G[v].push_back(u);
    }

    p[1] = -1;
    dfs(1,-1);

    dp(1);
    printf("%d
",max(d[1][0],d[1][1]));

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/TreeDream/p/7216888.html