题目的意思就是在直径上找一段距离不超过s的路径,使该路径的偏心距最小。

求出直径之后,显然我们可以用双指针扫描一段合法路径。设u1,u2...ut是直径上的点,d[ui]表示从ui出发能到达的最远距离(除直径),那么该路径的偏心距的表达式就是max(max{d[uk]},dist(u1,ui),dist(uj,ut)),其中i<=k<=j;根据直径的最长性,max{d[uk]}中k的取值可以变为1<=k<=t,因为d[ux](1<=x<=i)一定比dist(u1,ui)要小,这是根据直径的最长性可以推导的,j-t的那部分也同理。所以我们只需要用一个定值记录max{d[uk]}(1<=k<=t)就行了,也就是代码中的maxf。

最后要求最小偏心距,对于每段合法路径的偏心距取min就行了。复杂度O(n)。

 1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N=500005;
4 int to[N<<1],nxt[N<<1],edge[N<<1],head[N],tot;
5 int n,s,t,p,q;
6 int d[N],pre[N],a[N],b[N],f[N],sum[N];
7 bool v[N];
8
9 void add(int x,int y,int z){
10 nxt[++tot]=head[x];
11 head[x]=tot;
12 to[tot]=y;
13 edge[tot]=z;
14 }
15
16 void dfs1(int u,int f){
17 if(d[u]>d[p]) p=u;
18 for(int i=head[u];i;i=nxt[i]){
19 int v=to[i];
20 if(v==f) continue;
21 d[v]=d[u]+edge[i];
22 dfs1(v,u);
23 }
24 }
25
26 void dfs2(int u,int f){
27 if(d[u]>d[q]) q=u;
28 for(int i=head[u];i;i=nxt[i]){
29 int v=to[i];
30 if(v==f) continue;
31 d[v]=d[u]+edge[i];
32 pre[v]=i;
33 dfs2(v,u);
34 }
35 }
36
37 void dfs(int x){//求从x向外所能到达的最远距离
38 v[x]=true;
39 for(int i=head[x];i;i=nxt[i]){
40 int y=to[i];
41 if(v[y]) continue;
42 dfs(y);
43 f[x]=max(f[x],f[y]+edge[i]);
44 }
45 }
46
47 int main(){
48 cin>>n>>s;
49 tot=1;
50 for(int i=1;i<n;i++){
51 int x,y,z;
52 scanf("%d%d%d",&x,&y,&z);
53 add(x,y,z);add(y,x,z);
54 }
55 dfs1(1,0);
56 dfs2(p,0);
57 while(q!=p){
58 a[++t]=q;//存直径上的点
59 b[t+1]=edge[pre[q]];//存边权
60 q=to[pre[q]^1];
61 }
62 a[++t]=p;
63 for(int i=1;i<=t;i++) v[a[i]]=true;
64 int maxf=0;
65 for(int i=1;i<=t;i++){
66 dfs(a[i]);
67 maxf=max(maxf,f[a[i]]);
68 sum[i]=sum[i-1]+b[i];
69 }
70 int ans=1<<30;
71 for(int i=1,j=1;i<=t;i++){//双指针扫描
72 while(j<t&&sum[j+1]-sum[i]<=s) j++;
73 ans=min(ans,max(maxf,max(sum[i],sum[t]-sum[j])));
74 }
75 cout<<ans<<endl;
76 }

最新文章

  1. Linux设备文件简介(转载)
  2. Unity 编译apk启动出异常
  3. [Node.js] 使用File API 异步上传文件
  4. 每天2个android小例子----简单计算器源代码
  5. 利用Jquery实现http长连接(LongPoll)
  6. ARM开发板系统移植-----rootfs的制作
  7. xcode忽略警告
  8. silverlight 双坐标轴
  9. svn本地目录结构for window
  10. python calendar(日历)模块
  11. [wiki] Unix like
  12. DataTable行列转置
  13. Docker 网络之进阶篇
  14. LIMIT与OFFSET的使用
  15. Visual Studio2015安装过程以及单元测试
  16. Redis源码学习-Master&amp;Slave的命令交互
  17. LeetCode 961 N-Repeated Element in Size 2N Array 解题报告
  18. USB基础知识概论(版本:v0.9.2)
  19. Mysql 利用拷贝data目录文件的方式迁移mysql数据库
  20. Angular4-配置

热门文章

  1. 二分法求最长子序列长度(STL)(nlogn)
  2. MPI学习笔记(二):矩阵相乘的两种实现方法
  3. js实现全屏弹框
  4. 使用JDK的同步容器时,应该避免那些坑?
  5. 基于mpvue的框架开发微信小程序(搭建环境)
  6. ubuntu 下获取Let&#39;s Encrypt免费ssl证书
  7. Python 懂车帝全车系销量排行榜
  8. Luogu5019 铺设道路 (贪心)
  9. [HFCTF2020]EasyLogin-1|JWT身份伪造
  10. 自动化选课(Python + selenium