这是我的getroot函数,用oiwiki上的求法只能10pts 无法理解T_T
void getroot(int u,int fa)
{
sz[u]=1;//int mx=0;
mx[u]=0;
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];
if(v!=fa&&!vis[v])getroot(v,u),sz[u]+=sz[v],mx[u]=max(mx[u],sz[v]);
}
mx[u]=max(mx[u],S-sz[u]);
if(mx[u]<=mx[Root])Root=u; //可AC求法
// if(mx[u]<=S/2)Root=u; //OIWIKI上的求法
}
#include<iostream>
#include<algorithm>
#define int long long
using namespace std;
inline int rd()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9')f=ch=='-'?-1:1,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline void wr(int x)
{
if(x<0){putchar('-');wr(-x);return;}
if(x>9)wr(x/10);
putchar(char(x%10+'0'));
return;
}
const int N=4e4+100;
int n,to[N<<1],nxt[N<<1],head[N],val[N<<1],cnt;
int k,sz[N],mxsz,Root,vis[N],dep[N],d[N],S,ans,mx[N];
void add(int u,int v,int w)
{
to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;val[cnt]=w;
}
void getroot(int u,int fa)
{
sz[u]=1;//int mx=0;
mx[u]=0;
for(int i=head[u];i;i=nxt[i])
{
int v=to[i];
if(v!=fa&&!vis[v])getroot(v,u),sz[u]+=sz[v],mx[u]=max(mx[u],sz[v]);
}
mx[u]=max(mx[u],S-sz[u]);
if(mx[u]<=mx[Root])Root=u; //可行求法
// if(mx[u]<=S/2)Root=u; //OIWIKI上的求法
}
void gtdp(int u,int fa)
{
dep[++dep[0]]=d[u];
for(int i=head[u];i;i=nxt[i])
{
int v=to[i],w=val[i];
if(vis[v]||v==fa)continue;
d[v]=d[u]+w;
gtdp(v,u);
}
}
int gt(int u,int dis)
{
d[u]=dis;dep[0]=0;
gtdp(u,-1);
int l=1,r=dep[0],ret=0;
sort(dep+1,dep+dep[0]+1);
while (l<r)
if(dep[l]+dep[r]<=k)ret+=r-l,++l;
else --r;
return ret;
}
void go(int u)
{
vis[u]=1;
ans+=gt(u,0);
for(int i=head[u];i;i=nxt[i])
{
int v=to[i],w=val[i];
if(vis[v])continue;
ans-=gt(v,w);
Root=0;S=sz[v];
getroot(v,u);
go(Root);
}
}
signed main()
{
// freopen("A.in","r",stdin);
n=rd();
mx[0]=0x7fffffff;
for(int i=1;i<n;++i)
{
int u=rd(),v=rd(),w=rd();
add(u,v,w);
add(v,u,w);
}
k=rd();
S=n;
getroot(1,-1);
go(Root);
wr(ans);putchar('\n');
return 0;
}
/*
5
1 2 3
1 3 1
1 4 2
3 5 1
4
7
1 6 999
6 3 25
7 5 5
4 1 30
2 4 10
4 7 2
15
7 15
1 6 999
6 3 25
7 5 5
4 1 30
2 4 10
4 7 2
*/