zoukankan      html  css  js  c++  java
  • [ZJOI2008]骑士

    [ZJOI2008]骑士

    标签: DP


    题目链接

    题解

    把边看成无向的。
    其实就是求这个东西的最大独立集。
    但是这不是树,怎么求呢?
    其实还是一样的求法。
    对于每一个连通块。最多有这个联通块的大小数目的边。
    所以这个联通块只会有一个环。
    那么把这个环去掉一条边,强制这条边的两个端点不能都选,跑一个树形dp。

    Code

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<set>
    #include<map>
    using namespace std;
    #define ll long long
    #define REP(i,a,b) for(int i=(a),_end_=(b);i<=_end_;i++)
    #define DREP(i,a,b) for(int i=(a),_end_=(b);i>=_end_;i--)
    #define EREP(i,a) for(int i=start[(a)];i;i=e[i].next)
    inline int read()
    {
        int sum=0,p=1;char ch=getchar();
        while(!(('0'<=ch && ch<='9') || ch=='-'))ch=getchar();
        if(ch=='-')p=-1,ch=getchar();
        while('0'<=ch && ch<='9')sum=sum*10+ch-48,ch=getchar();
        return sum*p;
    }
    const int maxn=1e6+20;
    struct node {
        int v,next,from;
    };
    node e[maxn*2];
    int cnt=1,start[maxn];
    int n;
    int w[maxn],vis[maxn];
    ll ans,f[maxn],g[maxn];
     
    void addedge(int u,int v)
    {
        e[++cnt]=(node){v,start[u],u};
        start[u]=cnt;
    }
     
    void init()
    {
        n=read();
        REP(i,1,n)
        {
            w[i]=read();
            int u=read();
            addedge(u,i);
            addedge(i,u);
        }
    }
     
    int Del;
     
    void dfs1(int u,int fa)
    {
        if(vis[u]){Del=fa;return;}
        vis[u]=1;
        EREP(i,u)
        {
            int v=e[i].v;
            if(i==(fa^1))continue;
            dfs1(v,i);
        }
    }
     
    void dfs(int u,int fa)
    {
        f[u]=w[u];g[u]=0;
        EREP(i,u)
        {
            int v=e[i].v;
            if(v==fa || i==Del ||i==(Del^1))continue;
            dfs(v,u);
            f[u]+=g[v];
            g[u]+=max(f[v],g[v]);
        }
    }
     
    void doing()
    {
        REP(i,1,n)
        {
            if(vis[i])continue;
            dfs1(i,0);
            dfs(e[Del].from,0);
            ll A=g[e[Del].from],B;
            dfs(e[Del].v,0);
            B=g[e[Del].v];
            ans+=max(A,B);
        }
        cout<<ans<<endl;
    }
     
    int main()
    {
        init();
        doing();
        return 0;
    }
    
  • 相关阅读:
    求周期串的最小正周期
    Manacher's Algorithm
    高精度
    找x的两个素数因子使x=pq(Pollard_Rho)
    Intersection is not allowed!
    类欧几里得
    分数规划
    'sessionFactory' or 'hibernateTemplate' is required
    Struts2的动态方法,及result跳转方式,全局结果以及默认的action的配置
    配置Struts2及Struts2访问servlet api的方式
  • 原文地址:https://www.cnblogs.com/gzy-cjoier/p/7502745.html
Copyright © 2011-2022 走看看