• POJ1741


    树分治,每次把每个点的deep取出,排序。。。尺取法。。。

    # include <stdio.h>
    # include <stdlib.h>
    # include <iostream>
    # include <algorithm>
    # include <string.h>
    # define IL inline
    # define RG register
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    
    IL ll Read(){
        RG char c = getchar(); RG ll x = 0, z = 1;
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
        return x * z;
    }
    
    const int MAXN(20010), INF(2147483647);
    int n, cnt, fst[MAXN], to[MAXN], nxt[MAXN], w[MAXN], k;
    int size[MAXN], rt, sz, mx[MAXN], vis[MAXN];
    ll ans, d[MAXN];
    
    IL void Add(RG int u, RG int v, RG int f){  nxt[cnt] = fst[u]; to[cnt] = v; w[cnt] = f; fst[u] = cnt++;  }
    
    IL void Getroot(RG int u, RG int fa){
        size[u] = 1; mx[u] = 0;
        for(RG int e = fst[u]; e != -1; e = nxt[e]){
            if(vis[to[e]] || to[e] == fa) continue;
            Getroot(to[e], u);
            size[u] += size[to[e]];
            mx[u] = max(mx[u], size[to[e]]);
        }
        mx[u] = max(mx[u], sz - size[u]);
        if(mx[u] < mx[rt]) rt = u;
    }
    
    
    IL void Getdeep(RG int u, RG int fa, RG ll dis){
        d[++cnt] = dis;
        for(RG int e = fst[u]; e != -1; e = nxt[e]){
            if(vis[to[e]] || to[e] == fa) continue;
            Getdeep(to[e], u, dis + w[e]);
        }
    }
    
    IL ll Calc(RG int u, RG int f){
        cnt = 0; Getdeep(u, 0, f);
        sort(d + 1, d + cnt + 1);
        RG ll ret = 0, l = 1, r = cnt;
        while(l < r) if(d[r] + d[l] <= k) ret += r - l, l++; else r--;
        return ret;
    }
    
    IL void Solve(RG int u){
        ans += Calc(u, 0); vis[u] = 1;
        for(RG int e = fst[u]; e != -1; e = nxt[e]){
            if(vis[to[e]]) continue;
            ans -= Calc(to[e], w[e]);
            rt = 0; sz = size[to[e]];
            Getroot(to[e], u);
            Solve(rt);
        }
    }
    
    int main(RG int argc, RG char* argv[]){
        n = Read(); k = Read(); mx[0] = INF;
        while(n && k){
            Fill(fst, -1); Fill(vis, 0); rt = ans = cnt = 0; sz = n;
            for(RG int i = 1, u, v, f; i < n; i++) u = Read(), v = Read(), f = Read(), Add(u, v, f), Add(v, u, f);
            Getroot(1, 0); Solve(rt);
            printf("%lld
    ", ans);
            n = Read(); k = Read();
        }
        return 0;
    }
  • 相关阅读:
    [HAOI2015][bzoj 4033]树上染色(树dp+复杂度分析)
    20190716NOIP模拟赛T1 礼物(概率dp+状压)
    20190716NOIP模拟赛T2 通讯(tarjan缩点+贪心)
    延迟载入Dll(动态载入Dll)
    Dll重定向(尚存否?)
    delete和delete[] 区别
    06 序列号保护 学习分析(字符串)
    05 初识加壳脱壳
    04 复制删除行为IDA反汇编
    03 复制行为动态分析
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8206385.html
Copyright © 2020-2023  润新知