• [POJ3585]Accumulation Degree


    题面

    ( ext{Solution:})

    有些题目不仅让我们做树型 ( ext{dp}) ,而且还让我们换每个根分别做一次, 然后这样就愉快的 ( ext{TLE}) 了,所以我们要用一种方法快速知道所有根的答案。

    二次扫描与换根法:

    就是先选任意点作根做一遍 ( ext{dp}) ,求出相关信息,然后再从根往下 ( ext{dfs}) ,对每一个节点往下走之前进行自顶向下的推导,计算出 "换根" 后的解。

    就这题而言就是用父亲的换根后的答案来跟新自己换根前的答案,一般是 换根后父亲的答案+自己换根前的答案-自己对父亲换根后的贡献

    #include <set>
    #include <cmath>
    #include <cctype>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <assert.h>
    #include <algorithm>
    
    using namespace std;
    
    #define fir first
    #define sec second
    #define pb push_back
    #define mp make_pair
    #define LL long long
    #define INF (0x3f3f3f3f)
    #define mem(a, b) memset(a, b, sizeof (a))
    #define debug(...) fprintf(stderr, __VA_ARGS__)
    #define Debug(x) cout << #x << " = " << x << endl
    #define travle(i, x) for (register int i = head[x]; i; i = nxt[i])
    #define For(i, a, b) for (register int (i) = (a); (i) <= (b); ++ (i))
    #define Forr(i, a, b) for (register int (i) = (a); (i) >= (b); -- (i))
    #define file(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
    #define ____ debug("go
    ")
    
    namespace io {
        static char buf[1<<21], *pos = buf, *end = buf;
        inline char getc()
        { return pos == end && (end = (pos = buf) + fread(buf, 1, 1<<21, stdin), pos == end) ? EOF : *pos ++; }
        inline int rint() {
            register int x = 0, f = 1;register char c;
            while (!isdigit(c = getc())) if (c == '-') f = -1;
            while (x = (x << 1) + (x << 3) + (c ^ 48), isdigit(c = getc()));
            return x * f;
        }
        inline LL rLL() {
            register LL x = 0, f = 1; register char c;
            while (!isdigit(c = getc())) if (c == '-') f = -1;
            while (x = (x << 1ll) + (x << 3ll) + (c ^ 48), isdigit(c = getc()));
            return x * f;
        }
        inline void rstr(char *str) {
            while (isspace(*str = getc()));
            while (!isspace(*++str = getc()))
                if (*str == EOF) break;
            *str = '';
        }
        template<typename T> 
            inline bool chkmin(T &x, T y) { return x > y ? (x = y, 1) : 0; }
        template<typename T>
            inline bool chkmax(T &x, T y) { return x < y ? (x = y, 1) : 0; }    
    }
    using namespace io;
    
    const int N = 2e5 + 2;
    
    int n, T;
    int tot, head[N], ver[N<<1], nxt[N<<1], edge[N<<1];
    int D[N], F[N], in[N];
    
    void add(int u, int v, int w)
    { ver[++tot] = v, edge[tot] = w, nxt[tot] = head[u], head[u] = tot; }
    
    void DFS(int u, int f) 
    {
        D[u] = 0;
        for (int i = head[u]; i; i = nxt[i]) 
            if (ver[i] != f) 
            {
                DFS(ver[i], u);
                int v = ver[i];
                if (in[v] == 1) D[u] += edge[i];
                else D[u] += min(D[v], edge[i]);
            }
    }
    
    void DP(int u, int f) 
    {
        for (int i = head[u]; i; i = nxt[i]) 
            if (ver[i] != f) 
            {
                int v = ver[i];
                if (in[u] == 1) F[v] = D[v] + edge[i];
                else F[v] = D[v] + min(F[u] - min(edge[i], D[v]), edge[i]);
                DP(v, u);
            }
    }
    
    int main() {
    
        T = rint();
        while (T --) 
        {
            tot = 0; mem(head, 0); mem(in, 0); mem(D, 0); mem(F, 0);
    
            n = rint();
            for (int i = 1; i < n; ++ i)
            {
                int u = rint(), v = rint(), w = rint();
                add(u, v, w);
                add(v, u, w);
                in[u] ++, in[v] ++;
            }
    
            DFS(1, 0);
            F[1] = D[1];
            DP(1, 0);
            for (int i = 1; i <= n; ++ i)
                chkmax(F[1], F[i]);
            printf("%d
    ", F[1]);
        }
    }
    
  • 相关阅读:
    nodejs学习(一)--express+ejs生成项目
    react-native React Native version mismatch
    qrcode length overflow 生成二维码网址长度溢出解决办法
    禁止input输入空格
    微信开发:清除微信浏览器缓存
    多行文本溢出显示...的方法(-webkit-line-clamp)
    angular路由(自带路由篇)
    angular入门(基础篇)
    Python文件读写(open(),close(),with open() as f...)
    centos6.9使用yum安装mysql(简单粗暴,亲测有效)
  • 原文地址:https://www.cnblogs.com/cnyali-Tea/p/10505895.html
Copyright © 2020-2023  润新知