Description
给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K
Input
N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下来是k
Output
一行,有多少对点之间的距离小于等于k
Sample Input
7
1 6 13
6 3 9
3 5 7
4 1 3
2 4 20
4 7 2
10
1 6 13
6 3 9
3 5 7
4 1 3
2 4 20
4 7 2
10
Sample Output
5
HINT
Source
点分治。。嗯这次是完全自己写的
我还是丢论文吧。。
http://wenku.baidu.com/link?url=7a6LgoMZY7Xe5UpeOS7fF_bLLP7O4a0hSTvcRtPLT5H5Vx5ovrAn9ZkO70eb7BCNHClOu8OC4zijH3XhRBMB12pWySIWP187Q8oT7eLgNSC
因为忘记判断该点是否走过无限RE
#include<cstdio>
#include<algorithm>
using namespace std;
struct line
{
int s,t;
int x;
int next;
}a[80001];
int head[40001];
int edge;
inline void add(int s,int t,int x)
{
a[edge].next=head[s];
head[s]=edge;
a[edge].s=s;
a[edge].t=t;
a[edge].x=x;
}
int mini,minx;
int son[40001];
bool v[40001];
inline void find(int d,int fa,int s)
{
son[d]=0;
int i;
int tmp=0;
for(i=head[d];i!=0;i=a[i].next)
{
int t=a[i].t;
if(t!=fa&&!v[t])
{
find(t,d,s);
son[d]+=(son[t]+1);
tmp=max(tmp,son[t]+1);
}
}
int mx=max(tmp,s-tmp-1);
if(mx<minx||mx==minx&&d<mini)
{
minx=mx;
mini=d;
}
}
int sx[40001];
int dis[40001];
int p,k;
inline void dfs(int d,int fa)
{
int i;
for(i=head[d];i!=0;i=a[i].next)
{
int t=a[i].t;
if(t!=fa&&!v[t])
{
dis[t]=dis[d]+a[i].x;
p++;
sx[p]=dis[t];
dfs(t,d);
}
}
}
int ans;
inline void solve(int d)
{
v[d]=true;
int i,j;
int l,r;
p=0;
int p1;
for(i=head[d];i!=0;i=a[i].next)
{
int t=a[i].t;
if(!v[t])
{
dis[t]=a[i].x;
p++;
sx[p]=dis[t];
p1=p;
dfs(t,d);
sort(sx+p1,sx+p+1);
l=p1;
r=p;
while(l<r)
{
if(sx[l]+sx[r]<=k)
{
ans-=(r-l);
l++;
}
else
r--;
}
}
}
sort(sx+1,sx+p+1);
for(i=1;i<=p;i++)
if(sx[i]<=k)
ans++;
l=1;
r=p;
while(l<r)
{
if(sx[l]+sx[r]<=k)
{
ans+=(r-l);
l++;
}
else
r--;
}
for(i=head[d];i!=0;i=a[i].next)
{
int t=a[i].t;
if(!v[t])
{
mini=0;
minx=2100000000;
find(t,d,son[t]);
int root=mini;
solve(root);
}
}
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("data.out","w",stdout);
int n;
scanf("%d",&n);
int i;
int s,t,x;
for(i=1;i<=n-1;i++)
{
scanf("%d%d%d",&s,&t,&x);
edge++;
add(s,t,x);
edge++;
add(t,s,x);
}
mini=0;
minx=2100000000;
find(1,0,n);
int root=mini;
scanf("%d",&k);
solve(root);
printf("%d\n",ans);
return 0;
}