bzoj 1468: Tree

来源:互联网 发布:如何添加淘宝客服 编辑:程序博客网 时间:2024/06/04 00:27

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

Sample Output

5

HINT

Source

LTC男人八题系列


点分治。。嗯这次是完全自己写的

我还是丢论文吧。。

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;}


0 0