zoukankan      html  css  js  c++  java
  • 【BZOJ】1040: [ZJOI2008]骑士 环套树DP

    【题意】给定n个人的ai和bi,表示第i个人能力值为ai且不能和bi同时选择,求能力值和最大的选择方案。n<=10^6。

    【算法】环套树DP(基环树)

    【题解】n个点n条边——基环森林(若干环套树子图)。

    若原图是树,经典DP做法:f[i][0/1]表示i点选或不选的最大能力值和,则f[i][0]=Σmax{f[j][0],f[j][1]},f[i][1]=Σf[j][0]+a[i],j=son[i]。

    找环:dfs到访问过的点,标记环上的一条边。

    破环:和普通树上DP唯一的区别是,标记边两端不能同时为1,所以从两端AB开始分别进行一次树形DP,最后ans=max{f[A][0],f[B][0]}(这两个f[]是两次分别计算的结果)。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn=1000010;
    int n,tot,first[maxn],A,B,a[maxn];
    ll f[maxn][2];
    bool vis[maxn],d[maxn*2];
    struct edge{int v,from;}e[maxn*2];
    void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
    void dfs(int x,int fa){
        vis[x]=1;
        for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa){
            if(vis[e[i].v]){A=x;B=e[i].v;d[i]=d[i^1]=1;}
            else dfs(e[i].v,x);
        }
    }
    void dp(int x,int fa){
        //printf("x=%d
    ",x);
        f[x][0]=0;f[x][1]=a[x];
        for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa&&!d[i]){
            //printf("y=%d
    ",e[i].v);
            dp(e[i].v,x);
            //printf("[%lld]
    ",f[e[i].v][1]);
            f[x][0]+=max(f[e[i].v][0],f[e[i].v][1]);
            f[x][1]+=f[e[i].v][0];
        }
        //printf("%lld %lld
    ",f[x][0],f[x][1]);
    }
    int main(){
        scanf("%d",&n);
        int v;tot=1;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i],&v);
            insert(i,v);insert(v,i);
        }
        ll ans=0;
        for(int i=1;i<=n;i++)if(!vis[i]){
            dfs(i,0);
            dp(A,0);
            ll sum=f[A][0];
            dp(B,0);
            ans+=max(f[B][0],sum);
        }
        printf("%lld",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    python学习笔记 async and await
    python学习笔记 异步asyncio
    python学习笔记 协程
    python学记笔记 2 异步IO
    python学习笔记 可变参数关键字参数**kw相关学习
    逆波兰表达式 栈表达式计算
    Codeforces 270E Flawed Flow 网络流问题
    Codeforces 219D Choosing Capital for Treeland 2次DP
    kuangbin 带你飞 概率期望
    函数式编程思想:以函数的方式思考,第3部分
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8302239.html
Copyright © 2011-2022 走看看