Tree
題目描述
給定一棵 \(n\) 個節點的樹,每條邊有邊權,求出樹上兩點距離小於等於 \(k\) 的點對數量。
輸入格式
第一行輸入一個整數 \(n\),表示節點個數。
第二行到第 \(n\) 行每行輸入三個整數 \(u,v,w\) ,表示 \(u\) 與 \(v\) 有一條邊,邊權是 \(w\)。
第 \(n+1\) 行一個整數 \(k\) 。
輸出格式
一行一個整數,表示答案。
樣例 #1
樣例輸入 #1
7
1 6 13
6 3 9
3 5 7
4 1 3
2 4 20
4 7 2
10
樣例輸出 #1
5
提示
資料規模與約定
對於全部的測試點,保證:
- \(1\leq n\leq 4\times 10^4\)。
- \(1\leq u,v\leq n\)。
- \(0\leq w\leq 10^3\)。
- \(0\leq k\leq 2\times 10^4\)。
codes
#include<bits/stdc++.h>
using namespace std;
const int N=4e4+100;
const long long M=1e9+100;
struct edge{int y,x,n,z;}e[N<<1];
int lowbit(int x){return x&(-x);}
int n,m,cnt,head[N],q[N],top;
int siz[N],mxa[N],root,all,dis[N],c[N];
int ans=0;bool vis[N];
void upd(int x,int z){if(x<=0)return ;while(x<=m)c[x]+=z,x+=lowbit(x);}
int que(int x){if(x<=0)return 0;int sum=0;while(x)sum+=c[x],x-=lowbit(x);return sum;}
int po(int x){return que(x)-que(x-1);}
void ad(int x,int y,int z)
{
e[++cnt].n=head[x];
e[cnt].y=y;
e[cnt].x=x;
e[cnt].z=z;
head[x]=cnt;
}
void init()
{
scanf("%d",&n);
for(int i=1,x,y,z;i<n;++i)
{
scanf("%d%d%d",&x,&y,&z);
ad(x,y,z);ad(y,x,z);
}
scanf("%d",&m);
}
void getrt(int u,int fa)
{
siz[u]=1;
mxa[u]=0;
for(int i=head[u];i;i=e[i].n)
{
int v=e[i].y;
if(v==fa || vis[v])continue;
getrt(v,u);
siz[u]+=siz[v];
mxa[u]=max(mxa[u],siz[v]);
}
mxa[u]=max(mxa[u],all-siz[u]);
if(mxa[u]<mxa[root])root=u;
}
void getdis(int u,int fa)
{
if(dis[u]<=m)
{
++ans;
ans+=que(m-dis[u]);
}
for(int i=head[u];i;i=e[i].n)
{
int v=e[i].y;
if(vis[v] || v==fa)continue;
dis[v]=dis[u]+e[i].z;
getdis(v,u);
}
}
void ch(int u,int fa,int z)
{
if(dis[u]<=m)
upd(dis[u],z);
for(int i=head[u];i;i=e[i].n)
{
int v=e[i].y;
if(vis[v] || v==fa)continue;
ch(v,u,z);
}
}
void calc(int u)
{
int num=0;
for(int i=head[u];i;i=e[i].n)
{
int v=e[i].y;
if(vis[v])continue;
dis[v]=e[i].z;
getdis(v,0);
ch(v,u,1);
}
ch(u,0,-1);
}
void solve(int nw)
{
vis[nw]=1;
dis[nw]=0;
calc(nw);
for(int i=head[nw];i;i=e[i].n)
{
int v=e[i].y;
if(vis[v])continue;
all=siz[v];
root=0;
mxa[root]=M;
getrt(v,0);
solve(root);
}
}
void work()
{
all=n;
mxa[root]=M;
getrt(1,0);
solve(root);
cout<<ans;
}
int main()
{
init();
work();
return 0;
}