zoukankan      html  css  js  c++  java
  • BZOJ 1040: [ZJOI2008]骑士 | 在基环外向树上DP

    题目:

    http://www.lydsy.com/JudgeOnline/problem.php?id=1040


    题解:

    我AC了

    是自己写的

    超开心

    考虑断一条边

    这样如果根节点不选答案一定正确

    但是如果选了的话有可能他爸爸也选了

    所以我们强制他爸爸选再更新答案

    按照以上思路,存图存单向边即可

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define N 1000005
    using namespace std;
    typedef long long ll;
    int n,val[N],fa[N],cnt[N],head[N],tot,ecnt;
    bool vis[N];
    ll ans,f[N][2];
    struct edge
    {
        int nxt,v;
    }e[N];
    inline void add(int u,int v)
    {
        e[++ecnt].v=v;e[ecnt].nxt=head[u]; head[u]=ecnt;fa[v]=u;
    }
    inline void Dfs(int x)
    {
        int y;vis[x]=1;f[x][1]=val[x];
        for (int i=head[x];i;i=e[i].nxt)
        if (!vis[y=e[i].v])
        {
            Dfs(y);
            f[x][0]+=max(f[y][0],f[y][1]);
            f[x][1]+=f[y][0];
        }
    }
    inline void Dp(int x)
    {
        int rt,y;
        for (rt=x;cnt[rt]!=x;rt=fa[rt])
        cnt[rt]=x;
        Dfs(rt);
        x=fa[rt];
        f[x][1]=f[x][0];
        for (x=fa[x];x!=rt;x=fa[x])
        {
        f[x][0]=0;f[x][1]=val[x];
        for (int i=head[x];i,y=e[i].v;i=e[i].nxt)
            f[x][0]+=max(f[y][0],f[y][1]),f[x][1]+=f[y][0];
        }
        f[rt][1]=val[rt];
        for (int i=head[rt];i;i=e[i].nxt)
        f[rt][1]+=f[y=e[i].v][0];
        ans+=max(f[rt][0],f[rt][1]);
    }
    int main()
    {
        
        scanf("%d",&n);
        for (int i=1,u;i<=n;i++)
        {
        scanf("%d%d",&val[i],&u);
        add(u,i);
        }
        for (int i=1;i<=n;i++)
        if (!vis[i]) Dp(i);
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    MySQL之存储引擎
    MySQL之基础功能
    MySQL之正则表达式
    MySQL之数据类型
    MySQL之多表查询
    MySQL之单表查询
    linux命令useradd添加用户详解
    MySQL之数据操作
    MySQL之表操作
    MySQL之库操作
  • 原文地址:https://www.cnblogs.com/mrsheep/p/8240903.html
Copyright © 2011-2022 走看看