zoukankan      html  css  js  c++  java
  • 由 树的带权重心 衍申的对 树状DP 的感悟

    1.树状DP实质:

    通过转移方程使得可以由一个点的状态得到另外一个点的状态(例:树的带权重心中,由关于f[u]的转移方程能够得到f[v]的答案,附上链接

    2.关于转移方程的移动方向:

    u->v,f[u]的信息被每一个v使用,链接

    v->u,所有f[v]的信息被u聚合起来使用,无链接(参见普通的树的带权重心)

    3.一般要先v->u收集总数据到最终根节点,再用最终根节点的总数据转移状态改变到各个子节点去

    4.附上自己 树的带权重心的代码,题目

    #include<iostream>
    #include<iomanip>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N = 110;
    const int M = 10010;
    struct node
    {
        int v, next;
    } e[M];
    int p[N], eid;
    void init()
    {
        memset(p, -1, sizeof(p));
        eid = 0;
    }
    void insert(int u, int v)
    {
        e[eid].v = v;
        e[eid].next = p[u];
        p[u] = eid++;
    }
    int size[N], sum[N], f[N];
    int n;
    int dfs1(int u, int fa)
    {
        int sumSon = 0;
        f[u] = 0;
        for(int i = p[u]; i != -1; i = e[i].next)
        {
            int v = e[i].v;
            if(v != fa)
            {
                int son = dfs1(v, u);
                sumSon += son;
                f[u] += f[v]+son;
            }
        }
        sumSon += size[u];
        sum[u] = sumSon;
        return sumSon;
    }
    int dfs2(int u, int fa)
    {
        for(int i = p[u]; i != -1; i = e[i].next)
        {
            int v = e[i].v;
            if(v != fa)
            {
                f[v] = f[u]+sum[1]-2*sum[v];
                dfs2(v, u);
            }
        }
    }
    int main()
    {
        init();
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &size[i]);
            int v;
            scanf("%d", &v);
            if(v)
            {
                insert(i, v);
                insert(v, i);
            }
            scanf("%d", &v);
            if(v)
            {
                insert(i, v);
                insert(v, i);
            }
        }
        dfs1(1, -1);
        dfs2(1, -1);
        int ans = 2147483647;
        for(int i = 1; i <= n; i++)
            ans = min(ans, f[i]);
        printf("%d", ans);
        return 0;
    }
  • 相关阅读:
    JAVA入门到精通-第22/23讲-容器、集合类
    JAVA入门到精通-第24讲-容器、集合类
    JAVA入门到精通-第20/21讲-二进制.位运算.位移运算
    JAVA入门到精通-第19讲-多维数组
    JAVA入门到精通-第18讲-排序查找
    JAVA入门到精通-第16讲-数组
    spring demo
    springmvc启动加载指定方法
    Java 日志
    web前端框架
  • 原文地址:https://www.cnblogs.com/bear-xin/p/14322431.html
Copyright © 2011-2022 走看看