• BZOJ 1040: [ZJOI2008]骑士


    二次联通门 : BZOJ 1040: [ZJOI2008]骑士

    /*
        BZOJ 1040: [ZJOI2008]骑士
    
        基环树dp
    
        对于每个联通块内的环都断开
        做树形dp即可
    */
    #include <cstdio>
    #include <iostream>
    
    #define rg register
    inline void read (int &n)
    {
        rg char c = getchar ();
        for (n = 0; !isdigit (c); c = getchar ());
        for (; isdigit (c); n = n * 10 + c - '0', c = getchar ());
    }
    
    #define Max 1000006
    int _v[Max << 1], _n[Max << 1], EC = 1, list[Max];
    inline void In (int u, int v)
    { _v[++ EC] = v, _n[EC] = list[u], list[u] = EC; }
    typedef long long LL;
    int dfn[Max], st[Max], low[Max], top, DC, SC;
    bool is[Max];
    int a[Max];
    int key[Max];
    inline int cmin (int &a, int b) { if (b < a) a = b; }
    void Dfs (int n, int l)
    {
        st[++ top] = n; low[n] = dfn[n] = ++ DC;
        rg int i, v;
        for (i = list[n]; i; i = _n[i])
            if (i != l && i != (l ^ 1))
            {
                if (!dfn[v = _v[i]]) Dfs (v, i), cmin (low[n], low[v]); 
                else cmin (low[n], dfn[v]), is[v] = true;
            }
        if (low[n] == dfn[n])
            if (!is[n]) -- top;
            else
            {
                for (; st[top] != n; a[++ SC] = st[top --], is[a[SC]] = true);
                -- top; a[++ SC] = n;
            }
    }
    LL f[Max][2];
    using std :: max;
    LL data[Max][2];
    void Dp (int n, int F)
    {
        f[n][0] = 0, f[n][1] = key[n]; rg int i, v;
        for (i = list[n]; i; i = _n[i])
            if (!is[v = _v[i]] && v != F)
                Dp (v, n), f[n][0] += max (f[v][1], f[v][0]), f[n][1] += f[v][0];        is[n] = true;
    }
    int main (int argc, char *argv[])
    {
        int N; read (N); rg int i, j; int x;
        for (i = 1; i <= N; ++ i)
            read (key[i]), read (x), In (x, i), In (i, x);
        LL res = 0, s = 0;    
        for (i = 1; i <= N; ++ i)
        {
            if (is[i]) continue;
            top = 0, SC = 0, Dfs (i, 0), res = 0;
            for (i = 1; i <= SC; ++ i) Dp (a[i], 0);
            data[1][0] = f[a[1]][0], data[1][1] = 0;
            
            for (j = 2; j <= SC; ++ j)
            {
                data[j][0] = f[a[j]][0], data[j][1] = f[a[j]][1];
                data[j][0] += max (data[j - 1][0], data[j - 1][1]);
                data[j][1] += data[j - 1][0];
            }
    
            res = max (data[SC][1], data[SC][0]);
               data[1][0] = 0, data[1][1] = f[a[1]][1];
    
            for (j = 2; j <= SC; ++ j)
            {
                data[j][0] = f[a[j]][0], data[j][1] = f[a[j]][1];
                data[j][0] += max (data[j - 1][0], data[j - 1][1]);
                data[j][1] += data[j - 1][0];
            }
            res = max (res, data[SC][0]), s += res;
        }
        std :: cout << s;
        return 0;
    }
  • 相关阅读:
    防止重复点击
    刷新当前页面的几种方法
    PHP删除数组中空值
    json转化数组
    两个不能同时共存的条件orWhere查询
    SQLSTATE[42000]
    laravel一个页面两个表格分页处理
    Hash::make与Hash::check
    unbind()清除指定元素绑定效果
    二级联动
  • 原文地址:https://www.cnblogs.com/ZlycerQan/p/8135673.html
Copyright © 2020-2023  润新知