POJ1741 Tree

POJ1741 Tree
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 6232   Accepted: 1770

Description

Give a tree with n vertices,each edge has a length(positive integer less than 1001). 
Define dist(u,v)=The min distance between node u and v. 
Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k. 
Write a program that will count how many pairs which are valid for a given tree. 

Input

The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l. 
The last test case is followed by two zeros. 

Output

For each test case output the answer on a single line.

Sample Input

5 4

1 2 3

1 3 1

1 4 2

3 5 1

0 0

Sample Output

8
----------------------------------------------------------------
题目大意:见漆子超论文。
解题思路:见漆子超论文。表示一A,爽歪歪,原来是这样子的,还是觉得挺暴力的,只是避免了最坏情况而已。
#include <stdio.h>

#include <string.h>

#include <algorithm>

#include <queue>

#define clr(a,b) memset(a,b,sizeof(a))

using namespace std;



const int N=10005,M=20005,inf=0x3f3f3f3f;

int n,lim,eid,minn;

int head[N],ed[M],val[M],nxt[M];

int vis[N],fa[N],siz[N],dep[N],le,ri;



void addedge(int s,int e,int v){

    ed[eid]=e;val[eid]=v;nxt[eid]=head[s];head[s]=eid++;

}



int dfssize(int s,int f){

    fa[s]=f;siz[s]=1;

    for(int i=head[s];~i;i=nxt[i])

        if(ed[i]!=f&&!vis[ed[i]])siz[s]+=dfssize(ed[i],s);

    return siz[s];

}



void dfsroot(int s,int sum,int&root){

    int maxx=sum-siz[s];

    for(int i=head[s];~i;i=nxt[i]){

        int e=ed[i];if(e==fa[s]||vis[e])continue;

        dfsroot(e,sum,root);maxx=max(maxx,siz[e]);

    }

    if(maxx<minn){minn=maxx;root=s;}

}



void dfsdepth(int s,int d,int f){

    dep[ri++]=d;

    for(int i=head[s];~i;i=nxt[i])

        if(ed[i]!=f&&!vis[ed[i]])dfsdepth(ed[i],d+val[i],s);

}



int getdep(int a,int b){

    sort(dep+a,dep+b);int ret=0,e=b-1;

    for(int i=a;i<b;i++){

        if(dep[i]>lim)break;

        while(e>=a&&dep[e]+dep[i]>lim)e--;

        ret+=e-a+1;if(e>i)ret--;

    }

    return ret>>1;

}



int solve(int s){

    int sum=dfssize(s,-1),ret=0;minn=inf;

    int root;dfsroot(s,sum,root);

    vis[root]=1;

    for(int i=head[root];~i;i=nxt[i])

        if(ed[i]!=root&&!vis[ed[i]])

            ret+=solve(ed[i]);

    le=ri=0;

    for(int i=head[root];~i;i=nxt[i])

        if(ed[i]!=root&&!vis[ed[i]]){

            dfsdepth(ed[i],val[i],-1);ret-=getdep(le,ri);le=ri;

        }

    ret+=getdep(0,ri);

    for(int i=0;i<ri;i++)

        if(dep[i]<=lim)ret++;

        else break;

//    printf("%d %d %d %d\n",root,ret,le,ri);

    vis[root]=0;

    return ret;

}



int main(){

//    freopen("/home/axorb/in","r",stdin);

    while(scanf("%d%d",&n,&lim),n+lim){

        eid=0;clr(head,-1);

        for(int i=1;i<n;i++){

            int a,b,c;scanf("%d%d%d",&a,&b,&c);

            addedge(a,b,c);addedge(b,a,c);

        }

        clr(vis,0);

        printf("%d\n",solve(1));

    }

}

  

你可能感兴趣的:(tree)