记录编号 460904 评测结果 AAAAAAAAAA
题目名称 [POJ1741][男人八题]树上的点对 最终得分 100
用户昵称 Gravatarkemoto 是否通过 通过
代码语言 C++ 运行时间 0.711 s
提交时间 2017-10-18 19:23:00 内存使用 0.82 MiB
显示代码纯文本
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <iostream>
#define MAXN 10005
int first[MAXN],e = 1,n,m,root,Ans,S,size[MAXN],d[MAXN],deep[MAXN],f[MAXN],cnt;
bool vis[MAXN];


template<typename _t>
inline _t read(){
    _t x = 0,f = 1;
    char ch = getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch == '-') f = -f;
    for(;isdigit(ch);ch=getchar()) x = x * 10 + (ch^48);
    return x*f;
}

struct edge{
    int u,v,next,w;
}a[MAXN<<1];

inline void push(int u,int v,int w){
    a[e].u = u;a[e].v = v;a[e].w = w;
    a[e].next = first[u];first[u] = e++;
}

inline void G_root(int u,int fa){
    size[u] = 1; f[u] = 0;
    for(int i = first[u];i;i=a[i].next) {
        register int v = a[i].v;
        if(!vis[v] && v != fa) {
            G_root(v,u);
            size[u] += size[v];
            f[u] = std::max(f[u],size[v]);
        }
    }
    f[u] = std::max(f[u],S - f[u]);
    if(f[u] < f[root]) root = u;
}

inline void G_deep(int u,int fa){
    d[++cnt] = deep[u];
    for(int i = first[u];i;i=a[i].next)
        if(!vis[a[i].v] && a[i].v != fa)
            deep[a[i].v] = deep[u] + a[i].w,G_deep(a[i].v,u);
}

inline int G_Ans(int u){
    cnt = 0;G_deep(u,0); int Ans = 0;
    std::sort(&d[1],&d[cnt + 1]); 
    for(int l = 1,r = cnt;l<r;) 
        if(d[l] + d[r] <= m) Ans += r - l, l ++; 
        else r --;
    return Ans;
}

inline void dfs(int u){
    deep[u] = 0;vis[u] = 1; Ans += G_Ans(u); 
    for(int i = first[u];i;i=a[i].next)  
        if(!vis[a[i].v]) deep[a[i].v] = a[i].w,Ans -= G_Ans(a[i].v),
                S = size[u],root = 0,G_root(a[i].v,0),dfs(root);
}

int main(){
    freopen("poj1741_tree.in","r",stdin);
    freopen("poj1741_tree.out","w",stdout);
    while(scanf("%d%d",&n,&m) && (n || m)){
        memset(first,0,sizeof first); 
        memset(vis,0,sizeof vis);
        Ans = 0,e = 1;
        for(int i = 1;i<n;i++) {
            register int u = read<int>(),v = read<int>(),w = read<int>();
            push(u,v,w); push(v,u,w);
        } f[0] = 0x7fffffff;  S = n;
        root = 0; G_root(1,0); 
        dfs(root);
        printf("%d\n",Ans);
    }
    return 0;
}