# 洛谷4178 BZOJ1468 Tree题解点分治

BZOJ的链接（权限题）

# include<iostream>
# include<cstdio>
# include<algorithm>
# include<set>
# include<cmath>
using namespace std;
const int mn = 40005;
struct edge{int to,next,dis;};
edge e[mn*2];
{
e[++edge_max].to=y;
e[edge_max].dis=z;
}
bool vis[mn];
int n,k,ans;
int mx[mn],siz[mn],root,sum;
int d[mn],deep[mn];
void getroot(int x,int fa)
{
siz[x]=1,mx[x]=0;
{
int u=e[i].to;
if(u==fa || vis[u])
continue;
getroot(u,x);
siz[x]+=siz[u];
mx[x]=max(mx[x],siz[u]);
}
mx[x]=max(mx[x],sum-siz[x]);
if(mx[root]>mx[x])
root=x;
}
void getdeep(int x,int fa)
{
deep[++deep[0]]=d[x];
{
if(e[i].to==fa || vis[e[i].to])
continue;
d[e[i].to]=d[x]+e[i].dis;
getdeep(e[i].to,x);
}
}
int cal(int x,int now)
{
d[x]=now,deep[0]=0;
getdeep(x,0);
sort(deep+1,deep+1+deep[0]);
int t=0,l,r;
for(int l=1,r=deep[0];l<r;)
{
if(deep[l]+deep[r]<=k)
{
t+=r-l;
l++;
}
else r--;
}
return t;
}
void solve(int x)
{
vis[x]=1;
ans+=cal(x,0);
{
if(vis[e[i].to])
continue;
ans-=cal(e[i].to,e[i].dis);
sum=siz[e[i].to];
root=0;
getroot(e[i].to,root);
solve(root);
}
}
int main()
{
int x,y,z;
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
}
scanf("%d",&k);
mx[0]=1<<30,sum=n;
getroot(1,0);
solve(root);
printf("%d\n",ans);
return 0;
}

posted @ 2018-05-07 16:05  logeadd  阅读(130)  评论(0编辑  收藏  举报