zoukankan      html  css  js  c++  java
  • Bzoj 1131[POI2008]STA-Station (树形DP)

    Bzoj 1131[POI2008]STA-Station (树形DP)

    状态:
    (f[i])为以(i)为根的深度之和,然后考虑从他父亲转移.
    发现儿子的深度及其自己的深度(-1)
    其余的(+1),记录一下(size)就ok了
    转移:
    (f[i] = f[fa] + n - 2 * size[i])
    记忆化搜索即可.
    Bzoj 可能过不了,原因貌似是栈空间不足,可以去洛谷提交,我这里的解决方法是.记忆化搜索的时候用(n)作为开头.然后就过了.

    #include <iostream>
    #include <cstdio>
    #define ll long long
    const int maxN = 1000000 + 7;
    
    ll f[maxN],n; // f[i] = f[fa] + n - 2 * size[i];
    int size[maxN],dep[maxN],fa[maxN];
    
    struct Node {
        int v,nex;
    }Map[maxN << 1];
    int head[maxN],num;
    
    inline int read() {
        int x = 0,f = 1;char c = getchar();
        while(c < '0' || c > '9') {if(c == '-')f = -1;c = getchar();}
        while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
        return x * f;
    }
    
    inline ll max(ll a,ll b) {return a > b ? a : b;}
    
    void add_Node(int u,int v) {
        Map[++ num] = (Node) {v,head[u]};
        head[u] = num;
        return ; 
    }
    
    void work_fst(int now) {
        size[now] = 1;dep[now] = dep[fa[now]] + 1;
        for(int i = head[now];i;i = Map[i].nex) {
            int v = Map[i].v;
            if(v != fa[now]) {
                fa[v] = now;
                work_fst(v);
                size[now] += size[v];
            }
        }
        return ;
    }
    
    void work_dp(int now) {
        for(int i = head[now];i;i = Map[i].nex) {
            int v = Map[i].v;
            if(v != fa[now]) {
                f[v] = f[now] + n - 2 * size[v];
                work_dp(v);
            }
        }
    }
    
    int main() {
        n = read();
        for(int i = 1,u,v;i < n;++ i) {
            u = read();v = read();
            add_Node(u,v);
            add_Node(v,u);
        }
        dep[0] = -1;
        work_fst(n);
        for(int i = 1;i <= n;++ i)
            f[n] += dep[i];
        work_dp(n);
        ll ans = 0;
        for(int i = 1;i <= n;++ i)
            ans = max(ans,f[i]);
        for(int i = 1;i <= n;++ i)
            if(f[i] == ans) {printf("%d
    ", i);break;}
        return 0;
    }
    
  • 相关阅读:
    种子爆破&[GWCTF 2019]枯燥的抽奖
    Springboot学习笔记(三)
    Springboot学习笔记(二)
    Springboot学习笔记(一)
    深入理解java虚拟机阅读笔记(二)对象是否存活与垃圾收集算法
    深入理解java虚拟机阅读笔记(一)java内存区域
    OOP和AOP的区别
    浅谈对spring的理解
    mybatis逆向工程配置文件
    mybatis中${}和#{}的区别
  • 原文地址:https://www.cnblogs.com/tpgzy/p/9758845.html
Copyright © 2011-2022 走看看