1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #define N 600000
  5 using namespace std;
  6 int cnt,n,s,head[N],next[N*2],u[N*2],v[N*2],q[N],h,t,d[N],f[N],mx,rt1,mx1,from[N],zhan[N],tot,mark[N];
  7 int l,r,ans;
  8 void jia(int a1,int a2,int a3)
  9 {
 10     cnt++;
 11     next[cnt]=head[a1];
 12     head[a1]=cnt;
 13     u[cnt]=a2;
 14     v[cnt]=a3;
 15     return;
 16 }
 17 bool pan(int a1)
 18 {
 19     int L=1,R=tot;
 20     for(;zhan[1]-zhan[L]<=a1;L++);
 21     for(;zhan[R]-zhan[tot]<=a1;R--);
 22     if(zhan[L-1]-zhan[R+1]>s)
 23       return 0;
 24     return 1;
 25 }
 26 void dfs(int a1)
 27 {
 28     h=0;
 29     t=1;
 30     q[t]=a1;
 31     memset(f,0,sizeof(f));
 32     f[a1]=1;
 33     d[a1]=0;
 34     for(;h<t;)
 35       {
 36         h++;
 37         int p=q[h];
 38         for(int i=head[p];i;i=next[i])
 39           if(!f[u[i]])
 40             {
 41               if(mark[u[i]])
 42                  d[u[i]]=d[p];  
 43               else
 44                  d[u[i]]=d[p]+v[i];
 45               q[++t]=u[i];
 46               from[u[i]]=p;
 47               f[u[i]]=1;
 48             }
 49       }
 50     return;
 51 }
 52 int main()
 53 {
 54     scanf("%d%d",&n,&s);
 55     for(int i=1;i<n;i++)
 56       {
 57         int a1,a2,a3;
 58         scanf("%d%d%d",&a1,&a2,&a3);
 59         jia(a1,a2,a3);
 60         jia(a2,a1,a3);
 61       }
 62     dfs(1);
 63     mx=1;
 64     for(int i=1;i<=n;i++)
 65       if(mx<d[i])
 66         {
 67             mx=d[i];
 68             rt1=i;
 69         }
 70     dfs(rt1);
 71     mx=0;
 72     for(int i=1;i<=n;i++)
 73       if(mx<d[i])
 74         {
 75             mx=d[i];
 76             mx1=i;
 77         }
 78     r=d[mx1];
 79     zhan[++tot]=d[mx1];
 80     mark[mx1]=1;
 81     for(;mx1!=rt1;)
 82       {
 83         mx1=from[mx1];
 84         zhan[++tot]=d[mx1];
 85         mark[mx1]=1;
 86       }
 87     dfs(rt1);
 88     for(int i=1;i<=n;i++)
 89       if(d[i]>l)
 90         l=d[i];
 91     for(;l<=r;)
 92       {
 93         int mid=(l+r)>>1;
 94         if(pan(mid))
 95           {
 96             ans=mid;
 97             r=mid-1;
 98           }
 99         else
100           l=mid+1;
101       }
102     printf("%d\n",ans);
103     return 0;
104 }

显然最长距离最短,一定是在直径上,我们先DFS两遍找出直径,把直径上的边赋值成0,跑一遍dfs,找一个最大值作为l,二分答案判断。

posted on 2016-03-20 22:53  xiyuedong  阅读(188)  评论(0编辑  收藏  举报