题目

一颗\(n\)个点的树,求加入一条边点之后两点间最长距离的最小值 ;

\(n \le 100000\) ;

题解

  • 首先加入边的两个端点一定在直径上面,先\(dfs\)拎出直径来讨论(下标只代表直径上的点)

  • 设直径上的点\(i\)到直径起点的距离为\(s_i\), 直径以外的子树内的最长链\(g_i\)和最大深度\(d_i\)

  • 以 $ l = max \ { g_i } $ , $ r $ 为原树直径长度作为下界和上界,二分答案\(mid\)

  • 只需要考虑对于所有边\((i,j)(i<j)\),是否存在长度为\(L\)的\((a,b)(a<b)\),

    使得两点间最短距离都\(<=mid\),即使得:

    \[\begin{cases}
    &d_i+d_j+s_j-s_i \le mid \\
    &d_i+d_j+|s_i-s_a|+|s_j-s_b|+L \le mid\\
    \end{cases}
    \]

    中存在一个成立;

  • 若不满足1式,因为是小于等于,则展开2式绝对值

    \[\begin{cases}
    -s_a-s_b & \le mid-d_i-d_j-L-s_i-s_j \\
    -s_a+s_b & \le mid-d_i-d_j-L-s_i+s_j \\
    s_a-s_b & \le mid-d_i-d_j-L+s_i-s_j \\
    s_a+s_b & \le mid-d_i-d_j-L+s_i+s_j \\
    \end{cases}
    \]

    任意一个都成立;

  • 对\(d_i-s_i\)和\(d_i+s_i\)排序做two pointers可以得到满足(1)2的范围,分别求出(2)最紧的四个限制;

    (这里已经不需要管\(i<j\),因为如果\(i>j\)的话1不合法2一定不合法)

  • (2)的右边变成了定值,扫描\(s_i\)用two pointers求出四个范围,求交判断;

    #include<bits/stdc++.h>
    #define ll long long
    #define inf 1e18
    using namespace std;
    const int N=100010;
    int n,o=1,hd[N],L,fa[N],A,B,st[N],tot,a[N],b[N],vis[N];
    ll dis[N],s[N],d[N],g[N],f[N],mn1,mn2,lm1,lm2,lm3,lm4;
    struct Edge{int v,nt,w;}E[N<<1];
    char gc(){
    static char*p1,*p2,ch[1000000];
    if(p1==p2)p2=(p1=ch)+fread(ch,1,1000000,stdin);
    return(p1==p2)?EOF:*p1++;
    }//
    int rd(){
    int x=0;char c=gc();
    while(c<'0'||c>'9')c=gc();
    while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
    return x;
    }//
    void adde(int u,int v,int w){
    E[o]=(Edge){v,hd[u],w};hd[u]=o++;
    E[o]=(Edge){u,hd[v],w};hd[v]=o++;
    }//
    bool cmpa(int x,int y){return d[x]-s[x]<d[y]-s[y];}//
    bool cmpb(int x,int y){return d[x]+s[x]<d[y]+s[y];}//
    void dfs(int u,int F){
    fa[u]=F;
    for(int i=hd[u];i;i=E[i].nt){
    int v=E[i].v;
    if(v==F)continue;
    dis[v]=dis[u]+E[i].w;
    dfs(v,u);
    }
    }//
    void chkmax(ll&x,ll y){if(x<y)x=y;}//
    void chkmin(ll&x,ll y){if(x>y)x=y;}//
    void cal(int u,int F){
    g[u]=f[u]=0;
    for(int i=hd[u];i;i=E[i].nt){
    int v=E[i].v;
    if(v==F||vis[v])continue;
    cal(v,u);
    g[u]=max(max(g[u],g[v]),f[u]+f[v]+E[i].w);
    f[u]=max(f[u],f[v]+E[i].w);
    }
    }//
    bool check(ll mid){
    mn1=mn2=lm1=lm2=lm3=lm4=inf;
    for(int i=1,j=tot;i<=tot;++i){
    while(j&&d[a[i]]-s[a[i]]+d[b[j]]+s[b[j]]>mid){
    chkmin(mn1,-d[b[j]]-s[b[j]]);
    chkmin(mn2,-d[b[j]]+s[b[j]]);
    j--;
    }
    ll tmp=mid-d[a[i]]-L;
    chkmin(lm1,tmp-s[a[i]]+mn1);
    chkmin(lm2,tmp+s[a[i]]+mn1);
    chkmin(lm3,tmp-s[a[i]]+mn2);
    chkmin(lm4,tmp+s[a[i]]+mn2);
    }
    int j1=tot+1,j2=1,j3=0,j4=tot;
    for(int i=1;i<=tot;++i){
    while(j1>1&&-s[i]-s[j1-1]<=lm1)j1--;
    while(j2<=tot&&s[i]-s[j2]>lm2)j2++;
    while(j3<tot&&-s[i]+s[j3+1]<=lm3)j3++;
    while(j4>=1&&s[i]+s[j4]>lm4)j4--;
    int l=max(j1,j2),r=min(j3,j4);
    if(l<=r)return true;
    }
    return false;
    }
    int main(){
    // freopen("tree.in","r",stdin);
    // freopen("tree.out","w",stdout);
    while(1){
    n=rd();L=rd();o=1;tot=0;
    if(!n&&!L)break;
    for(int i=1;i<=n;++i)hd[i]=0;
    for(int i=1,u,v,w;i<n;++i){u=rd(),v=rd(),w=rd();adde(u,v,w);}
    dis[A=1]=0;dfs(1,0);
    for(int i=1;i<=n;++i)if(dis[i]>dis[A])A=i;
    dis[B=A]=0;dfs(A,0);
    for(int i=1;i<=n;++i)if(dis[i]>dis[B])B=i;
    cal(1,0);
    ll r=g[1],l=0;
    for(int i=B;i;i=fa[i])st[++tot]=i,vis[i]=1;
    reverse(st+1,st+tot+1);
    for(int i=1;i<=tot;++i){
    a[i]=b[i]=i;
    cal(st[i],0);
    d[i]=f[st[i]];
    s[i]=dis[st[i]];
    l=max(l,g[st[i]]);
    }
    for(int i=1;i<=tot;++i)vis[st[i]]=0;
    sort(a+1,a+tot+1,cmpa);
    sort(b+1,b+tot+1,cmpb);
    while(l<r){
    ll mid=(l+r)>>1;
    if(check(mid))r=mid;
    else l=mid+1;
    }
    printf("%lld\n",l);
    }//
    return 0;
    }

【loj2262】【CTSC2017】网络的更多相关文章

  1. [CTSC2017]网络

    [CTSC2017]网络 连一条长度为len的边,使得基环树的直径最小 结论:一定连在某条直径两个点上(否则更靠近不劣) 然后二分答案判定. dp[i]:链上一个点往下延伸的最大深度 考虑对于任意两个 ...

  2. BZOJ 4901 [CTSC2017]网络

    题解: 只会O(n log^2 n) O(n log n)先留坑 不开long long 0 分!!!! #include<iostream> #include<cstdio> ...

  3. uoj #298. 【CTSC2017】网络

    #298. [CTSC2017]网络 一个一般的网络系统可以被描述成一张无向连通图.图上的每个节点为一个服务器,连接服务器与服务器的数据线则看作图上的一条边,边权为该数据线的长度.两个服务器之间的通讯 ...

  4. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  5. Android请求网络共通类——Hi_博客 Android App 开发笔记

    今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. ...

  6. 网络原因导致 npm 软件包 node-sass / gulp-sass 安装失败的处理办法

    如果你正在构建一个基于 gulp 的前端自动化开发环境,那么极有可能会用到 gulp-sass ,由于网络原因你可能会安装失败,因为安装过程中部分细节会到亚马逊云服务器上获取文件.本文主要讨论在不变更 ...

  7. Virtual Box配置CentOS7网络(图文教程)

    之前很多次安装CentOS7虚拟机,每次配置网络在网上找教程,今天总结一下,全图文配置,方便以后查看. Virtual Box可选的网络接入方式包括: NAT 网络地址转换模式(NAT,Network ...

  8. 前端网络、JavaScript优化以及开发小技巧

    一.网络优化 YSlow有23条规则,中文可以参考这里.这几十条规则最主要是在做消除或减少不必要的网络延迟,将需要传输的数据压缩至最少. 1)合并压缩CSS.JavaScript.图片,静态资源CDN ...

  9. 猫哥网络编程系列:HTTP PEM 万能调试法

    注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...

随机推荐

  1. Unity - 绘制正五边形网格

    本文简述了Unity中绘制正五边形网格的基本方法:计算顶点信息.设置三角形覆盖信息.创建配置mesh 绘制方法 基本思路:计算出五边形顶点坐标信息作为数组,设置三角形包围方式,再创建新的mesh配置v ...

  2. form表单提交数据给后台

    1.完整登录示例 1. form表单往后端提交数据注意三点 1.所有获取用户输入标签都应该放在form表单里面 2.action属性控制往哪儿提交,method一般都是设置成post 3.提交按钮必须 ...

  3. 【转载】C#中List集合使用IndexOf判断元素第一次出现的索引位置

    在C#的List集合操作中,有时候需要判断元素对象在List集合中第一次出现的索引位置信息,此时需要使用到List集合的IndexOf方法来判断,如果元素存在List集合中,则IndexOf方法返回所 ...

  4. ASUS笔记本,更换了固态硬盘,重装系统前后开机都自动进入BIOS界面

    解决方法:advanced标签中sata configration回车进入,如有识别硬盘设备,按F9恢复BIOS默认设置,按F10保存后重启. 如有自行安装过系统,Security-Secure Bo ...

  5. vue中监听页面是否有回车键按下

    需求:当我在登录页面输入密码和账号后,按下回车键实现登录 mounted(){ let _this = this document.onkeydown = function(e) { if(e.key ...

  6. EXPORT_SYMBOL

    EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static函数和变量都会自动导入到kernel 空间 作用 EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开, ...

  7. css 和常用快捷键

    一.css概述: 1.规则:CSS 规则由选择器,以及一条或多条声明两个部分构成. 2.选择器:选择器通常是您需要改变样式的 HTML 元素. 3.声明:声明是您要设置的样式(每条声明由一个属性和一个 ...

  8. wokerman随笔

    linux环境检查是否满足workerman要求: curl -Ss http://www.workerman.net/check.php | php workerman依赖扩展:pcntl扩展.po ...

  9. 11g包dbms_parallel_execute在海量数据处理过程中的应用

    11g包dbms_parallel_execute在海量数据处理过程中的应用 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也 ...

  10. 【RAC】rac环境下的数据库备份与还原

    [RAC]rac环境下的数据库备份与还原 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~ ...