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

    这个题,我们发现,他有两点比较坑人的地方。。。

    1.这个图里面有多个联通块。。。

    2.这不是一棵好看的树,它可能有环。。。

    对于第一个,我们有一个bool数组存储,处理就好了。。。

    那么对于第二个,我们可以发现,这个图中最多有一个环,那么我们把环断开。。。

    对于每个端点做一次DP,这样结果就出来了。。。QAQ。。。

    呆码:

    #include<iostream>
    #include<cstdio>
    #define N 1000010
    #define ll long long
    using namespace std;
    
    struct asd{
        int nxt;
        int to;
    } a[N];
    
    int head[N],fa[N],ft[N];
    ll f[2][N],ans;
    int num,n;
    bool use[N];
    
    inline void add(int x,int y)
    {
        a[++num].nxt=head[x];
        a[num].to=y;
        head[x]=num;
    }
    
    inline void dp(int u,int father)
    {
        use[u]=1;
        f[1][u]=ft[u];
        f[0][u]=0;
        for(int i=head[u];i;i=a[i].nxt)
        {
            int to=a[i].to;
            if(to==father) { f[1][to]=-999999999; continue; }
            dp(to,father);
            f[0][u]=max(f[0][u],max(f[0][u]+f[1][to],f[0][u]+f[0][to]));
            f[1][u]=max(f[1][u],f[1][u]+f[0][to]);
        }
    }
    
    inline void make(int x)
    {
        while(!use[x])
        {
            use[x]=1;
            x=fa[x];
        }
        int y=fa[x];
        dp(x,x);
        ll cnt=max(f[0][x],f[1][x]);
        dp(y,y);
        ans+=max(cnt,max(f[0][y],f[1][y]));
    }
    
    int main()
    {
        scanf("%d",&n);
        int x;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&ft[i]);
            scanf("%d",&x);
            add(x,i);
            fa[i]=x;
        }
        for(int i=1;i<=n;i++)
            if(!use[i]) make(i);
        printf("%lld
    ",ans);
    }
    代码
  • 相关阅读:
    1101-Trees on the Level
    1099-移动小球
    1096-组合数
    Windows环境配置Apache+Mysql+PHP
    ArtDialog简单使用示例
    实现数字与字母的随机数
    SQLServer2005:在执行批处理时出现错误。错误消息为: 目录名无效
    sql语句总结
    在SQL SErver中实现数组功能
    aspnet_regiis.exe 的用法
  • 原文地址:https://www.cnblogs.com/zzzyc/p/9276276.html
Copyright © 2011-2022 走看看