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
  • 相关阅读:
    jvm基本结构和解析
    多态的意思
    java中对象的简单解读
    double类型和int类型的区别
    python 解析xml文件
    win10不能映射Ubuntu共享文件
    Qt程序打包
    Ubuntu boot分区文件误删,系统无法启动,怎么解
    ubuntu Boot空间不够问题“The volume boot has only 5.1MB disk space remaining”
    Ubuntu 分辨率更改 xrandr Failed to get size of gamma for output default
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8302239.html
Copyright © 2011-2022 走看看