POJ 1741 Tree

The first contact with tree divide-and-conquer, this is done by point divide-and-conquer.
If you don't know how to divide and conquer trees, you can read the paper of National Training Team in 2009 first.
https://wenku.baidu.com/view/1bc2e4ea172ded630b1cb602.html
https://wenku.baidu.com/view/60c6aa1ffc4ffe473368aba8.html
These two are pdf's and ppt's.
Reference resources: http://blog.csdn.net/qq_31759205/article/details/75095962
Seek how many pairs of dist (u, v)<=k, a path, either through the root node, or in the subtree, so recursive processing. The path through the root node can also be divided into two ends of the path in the same subtree or in different subtrees.

Before processing, the center of gravity of the tree is calculated, and the center of gravity is used as the root node to dfs to prevent the tree from degenerating into a chain.
The path through the root node is processed first, and depth[i] denotes the distance between the node and the tree root. The dfs calculates the distance from each node to the root of the tree, ranks it in ascending order, and puts two labels i,j, one finger and one finger tail, so that the label moves forward until depth[i] + depth [j] <= K. At this time, the node from the root node depth[i], there are j-i nodes and the path length <= k that they are connected to, then I moves to the right and repeats the above steps, provided that I < j]. This calculates the path of the root node, which is subtracted from the same subtree at both ends of the path. I'm not very good at expressing it. I can understand the code at a glance.
As for the path in the subtree, it's just the root node. Recursive processing is good.

When we did this, we took a look at the discussion board and found that when dealing with the subtree recursively, the number of nodes came according to all the nodes of the whole tree, so we could not find the center of gravity.

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

const int MAXN = 10010;
const int MAXM = 20020;
struct Edge
{
    int to,w,next;
}edge[MAXM];
int head[MAXN];
int son[MAXN];
int depth[MAXN];
int dr;
int n,k,tot,tmd;
bool vis[MAXN];

void init()
{
    tot = 0;
    memset(son,0,sizeof(son));
    memset(vis,0,sizeof(vis));
    memset(head,-1,sizeof(head));
}

void addedge(int u, int v, int w)
{
    edge[tot].to = v;
    edge[tot].w = w;
    edge[tot].next = head[u];
    head[u] = tot++;
}

void getRoot(int N, int u, int fa, int &root)
{
    son[u] = 1;
    int ans = 0;
    for(int i = head[u]; i != -1; i = edge[i].next)
    {
        int v = edge[i].to;
        if(v == fa || vis[v]) continue;
        getRoot(N,v,u,root);
        son[u] += son[v];
        ans = max(ans,son[v]);
    }
    ans = max(ans,N-son[u]);
    if(ans < tmd)
    {
        tmd = ans;
        root = u;
    }
}

void getDepth(int u, int fa, int dep)
{
    depth[dr++] = dep;
    for(int i = head[u]; i != -1; i = edge[i].next)
    {
        int v = edge[i].to;
        int w = edge[i].w;
        if(v == fa || vis[v]) continue;
        getDepth(v,u,dep+w);
    }
}

int calc(int u, int dep)
{
    dr = 0;
    int ret = 0;
    getDepth(u,-1,dep);
    sort(depth,depth+dr);
    int i = 0, j = dr-1;
    while(i < j)
    {
                            //Forgetting to write I < j, wa twice
        while(depth[i]+depth[j] > k && i < j) --j;
        ret += (j-i);
        ++i;
    }
    return ret;
}

int solve(int u, int N)
{
    int root,ret = 0;
    tmd = MAXN;
    getRoot(N,u,-1,root);
    vis[root] = true;
    ret += calc(root,0);
    for(int i = head[root]; i != -1; i = edge[i].next)
    {
        int v = edge[i].to;
        if(vis[v]) continue;
        int w = edge[i].w;
        ret -= calc(v,w);
        ret += solve(v,son[v]);
    }
    return ret;
}

int main()
{
    int a,b,w;
    while(scanf("%d %d",&n,&k) && n+k)
    {
        init();
        for(int i = 0; i < n-1; ++i)
        {
            scanf("%d %d %d",&a,&b,&w);
            addedge(a,b,w);
            addedge(b,a,w);
        }
        printf("%d\n",solve(1,n));
    }
    return 0;
}

Added by Baez on Wed, 29 May 2019 20:25:55 +0300