zoj 3527 带环的树形DP

很好的树形DP,破环为树;

这道题目很特殊,看到的时候根本无从下手,因为以前没接触过这种类型的树形DP,网上搜了一下发现自己简直弱爆了。。

这是一类最简单的树形DP,考虑某个节点选或不选,然后把两种状态从叶子向根更新上去即可,但是这道题中给你的不是一棵树,是图,特殊的图

每个点都只有一个父亲(或一个儿子),所以形成的环是简单环,所以可以考虑破环,从环上的一个点出发开始DP,这个点的两种状态(选或不选)分别枚举一下

View Code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long lld;
const lld inf = (lld)1<<50;
const int M = 100010;
int w[M];
int n;
int head[M],nxt[M],pnt[M],wi[M],p[M];
int E;
lld dp[M][2];
void add(int a,int b,int w)
{
    pnt[E]=b;
    wi[E]=w;
    nxt[E]=head[a];
    head[a]=E++;
}
void dfs(int u,int F)
{
    dp[u][0]=0;
    dp[u][1]=w[u];
    for(int i=head[u];i!=-1;i=nxt[i])
    {
        //printf("to=%d\n",pnt[i]);
        if(pnt[i]!=F)
            dfs(pnt[i],F);
        dp[u][0]+=max(dp[pnt[i]][0],dp[pnt[i]][1]);
        dp[u][1]+=max(dp[pnt[i]][0],dp[pnt[i]][1]+wi[i]);
    }
}
lld solve(int u)
{//printf("u=%d\n",u);
    dp[u][0]=0;
    dp[u][1]=-inf;//不选u,这个状态不合法
    lld ans1=0,ans2=0;
    for(int i=head[u];i!=-1;i=nxt[i])
    {
        //printf("%d %d\n",pnt[i],u);
        dfs(pnt[i],u);
        ans1+=max(dp[pnt[i]][0],dp[pnt[i]][1]);
    }
    //printf("u=%d\n",u);
    dp[u][0]=-inf;//选u,这个状态不合法
    dp[u][1]=w[u];
    for(int i=head[u];i!=-1;i=nxt[i])
    {
        //puts("bug");
        dfs(pnt[i],u);
        ans2+=max(dp[pnt[i]][0],dp[pnt[i]][1]+wi[i]);
    }
    return max(ans1,ans2);
}
int vis[M];
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        E=0;
        fill(head,head+n+1,-1);
        fill(p,p+n+1,-1);
        for(int i=1,j;i<=n;i++)
        {
            scanf("%d%d%d",&w[i],&j,&p[i]);
            add(p[i],i,j);
        }
    //    printf("E=%d\n",E);
        fill(vis,vis+n+1,-1);
        lld ans=0;
        for(int i=1,j;i<=n;i++)
        {
             if(vis[i]!=-1) continue;
             for(j=i;vis[j]==-1;j=p[j])
                 vis[j]=i;
        //     printf("%d %d\n",vis[j],i);
             if(vis[j]==i) ans+=solve(j);
        }
        printf("%lld\n",ans);
    }
    return 0;
}
posted @ 2012-07-11 23:10  Because Of You  Views(790)  Comments(0Edit  收藏  举报