//可以递归的寻找点对。对于当前查找的树来说,首先找到该树的重心,作为根。
如果点对之间的路径不经过根,就查找它的子树;
否则按以下方法寻找:
记录每个点的深度,存在A数组里,找到所有A数组中满足A[i]+A[j]<=k的数对个数,假设为a;
找到所有不经过根且同样满足上面条件的点对数目(这里可以通过查找所有子树的方法来做),设为b;
然后(a-b)就是所有经过当前查找的树的根根且满足题目条件的点对个数。
这样把以所有查找的树的结果加起来就可以了
<span style="font-size:12px;">#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 2100000000
using namespace std;
#define N 10010
int n,k,cot,head[N],vis[N],son[N],core,mi,ans,cnt;
int A[N],B[N];
struct edge
{
int to,next,v;
}e[N*3];
void addedge(int u,int v,int w)
{
e[cot].v=w;
e[cot].to=v;
e[cot].next=head[u];
head[u]=cot++;
}
void dfsdepth(int x,int fa,int dep)
{
A[cnt++]=dep;
for(int i=head[x];i!=-1;i=e[i].next)
{
int j=e[i].to;
if(!vis[j]&&j!=fa)
{
dfsdepth(j,x,dep+e[i].v);
}
}
}
int dfscore(int x,int fa,int sum)
{
int num=1;
int ma=0;
for(int i=head[x];i!=-1;i=e[i].next)
{
int j=e[i].to;
if(!vis[j]&&j!=fa)
{
int t=dfscore(j,x,sum);
ma=max(ma,t);
num+=t;
}
}
ma=max(ma,sum-num);
if(ma<mi)
{
mi=ma;core=x;
}
return son[x]=num;
}
int get(int root,int init)
{
cnt=0;
dfsdepth(root,0,init);
sort(A,A+cnt);
int j=cnt-1,i=0,res=0;
while(i<j)
{
while(i<j&&A[j]+A[i]>k)j--;
res+=j-i;
i++;
}
return res;
}
void dfs(int root,int sum)
{
mi=inf;
dfscore(root,0,sum);
vis[core]=1;
ans+=get(core,0);
for(int i=head[core];i!=-1;i=e[i].next)
{
int j=e[i].to;
if(!vis[j])
{
ans-=get(j,e[i].v);
dfs(j,son[j]);
}
}
}
int main()
{
while(scanf("%d%d",&n,&k),n+k)
{
int a,b,c;cot=0;
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,c),addedge(b,a,c);
}
ans=0;
dfs(1,n);
printf("%d\n",ans);
}
return 0;
}
</span>