点分治入门模

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<stdbool.h>

using namespace std;

const int maxn = 1e4 + 7;

struct node
{
    int to, next, val;
};

int son[maxn], dis[maxn], deep[maxn], vis[maxn], head[maxn], sz[maxn];
int n, m, root, all, ans, tot = 0, k;
node edge[maxn<<2];

void add(int u, int v, int val)
{
    edge[tot] = (node){v, head[u], val};
    head[u] = tot++;
}

void getroot(int x, int fa)
{
    sz[x] = 1;
    son[x] = 0;
    for(int i = head[x]; ~i; i = edge[i].next)
    {
        int to = edge[i].to;
        if(to == fa || vis[to]) continue;
        getroot(to, x);
        sz[x] += sz[to];
        son[x] = max(son[x], sz[to]);
    }
    son[x] = max(all - sz[x], son[x]);
    if(son[x] < son[root]) root = x;
}

void getdeep(int x, int fa)
{
    deep[++deep[0]] = dis[x];
    //printf("%d\n", dis[x]);
    for(int i = head[x]; ~i; i = edge[i].next)
    {
        //printf("%d\n", i);
        int to =  edge[i].to;
        if(to == fa || vis[to]) continue;
        dis[to] = dis[x] + edge[i].val;
        getdeep(to, x);
    }
}

int cal(int x, int d)
{
    dis[x] = d;
    deep[0] = 0;
    getdeep(x, 0);
    sort(deep + 1, deep + 1 + deep[0]);
    int an = 0;
   // printf("%d\n", deep[0]);
    for(int l = 1, r = deep[0]; l < r;)
    {
        //printf("%d %d\n", l, r);
        if(deep[l] + deep[r] <= k)
        {
            an += r - l;
            l++;
        }
        else
            r--;
    }
    return an;
}

void work(int x)
{
    vis[x] = 1;
    ans += cal(x, 0);
   // printf("%d\n", x);
    //printf("%d\n", ans);
    for(int i = head[x]; ~i; i = edge[i].next)
    {
        int to = edge[i].to;
        if(vis[to]) continue;
        ans -= cal(to, edge[i].val);
        all = sz[to];
        root = 0;
        getroot(to, x);
        work(root);
    }
}

int main()
{
    while(scanf("%d%d", &n, &k) && (n  || k))
    {
        memset(head, -1, sizeof(head));
        memset(vis,  0, sizeof(vis));
        tot = 0;
        for(int i = 1; i < n; i++)
        {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            add(v, u, w);
            add(u, v, w);
        }
        all = n;
        root = ans = 0;
        son[0] = 0x3f3f3f3f;
        getroot(1, 0);
        work(root);
        printf("%d\n", ans);
    }
    return 0;
}



发布了40 篇原创文章 · 获赞 13 · 访问量 870

猜你喜欢

转载自blog.csdn.net/weixin_43891021/article/details/98367422
今日推荐