当前位置: 首页 > news >正文

P1099 树网的核

传送门

BZOJ 上有加强版的数据 :$n<=10^6$,传送门

题面有点长...

考虑先把树的直径求出来,然后瞎搞一下

考虑直径上的点对答案的贡献,显然两个端点的贡献是最大的,可以直接在直径上用一个双指针维护一下左右边界 $l,r$,每次 $r$ 向右走,然后 $l$ 跟着走,贪心地想,显然 $l$ 能不走就不走是最优的

这样就可以尽可能地覆盖直径,使直径两端对答案贡献尽可能小了

然后考虑非直径的点的贡献,可以发现非直径的点对答案的贡献最多就是它到直径的距离,这样直接枚举所有直径点然后往非直径点 $dfs$ 求最大深度就行了

那如果此直径点没有被选择对答案有影响吗?

没有,因为它的贡献不会大于之前计算的直径两端点的贡献,看图理解(横着的一条路径是直径):

显然 $y$ 到 $x$ 距离一定不会大于 $z$ 到 $x$ 的距离,不然直径就不是横着的这条了

所以对答案的贡献显然 $z$ 会更大些

所以可以直接取 $max$

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=5e5+7;
int fir[N],from[N<<1],to[N<<1],val[N<<1],cnt;
inline void add(int &a,int &b,int &c)
{
    from[++cnt]=fir[a];
    fir[a]=cnt; to[cnt]=b; val[cnt]=c;
}
int dis[N],fa[N];//dis是到根的距离,fa是父亲
int k;//最深点编号
bool p[N];//是否是直径端点
void dfs(int x,int f)//dfs求最深节点的编号和dis
{
    fa[x]=f;
    if(dis[x]>dis[k]) k=x;
    for(int i=fir[x];i;i=from[i])
    {
        int &v=to[i]; if(v==f||p[v]) continue;//注意不走直径
        dis[v]=dis[x]+val[i]; dfs(v,x);
    }
}
int n,s,rt,ans=1e9+7;
int main()
{
    int a,b,c;
    n=read(); s=read();
    for(int i=1;i<n;i++)
    {
        a=read(); b=read(); c=read();
        add(a,b,c); add(b,a,c);
    }
    k=1; dfs(k,0);//找到直径的一个端点
    rt=k; dis[rt]=0; dfs(k,0);//找到另一个端点
    for(int l=k,r=k;l;l=fa[l])
    {
        while(dis[r]-dis[l]>s) r=fa[r];//尺取法动态维护左右边界
        ans=min(ans, max(dis[l],dis[k]-dis[r]) );
    }
    for(int i=k;i;i=fa[i]) p[i]=1;//标记直径节点
    for(int i=k;i;i=fa[i])
    {
        k=i; dis[i]=0;
        dfs(i,fa[i]);//求每个非直径节点到直径的距离
        //可以发现此处的dfs不会更新k
    }
    for(int i=1;i<=n;i++) ans=max(ans,dis[i]);//取max
    printf("%d",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/LLTYYC/p/10835206.html

相关文章:

  • Spectral analysis——光谱分析
  • iptables
  • 视觉暂留:视觉暂留
  • qt环境配置
  • 提升Scrapy框架爬取数据效率的五种方式
  • 详解Linux运维工程师必备技能
  • c++实现字符串分割函数--split()
  • 基于预计算的全局光照技术
  • java实现多线程(下)
  • 球谐光照——杂谈——待完成
  • 基于体素的全局光照技术
  • 路径追踪技术
  • 辐射度方法
  • [计算机体系结构:量化研究方法]学习笔记:Chapter 1
  • 基于预计算辐射传递的全局光照技术
  • $translatePartialLoader加载失败及解决方式
  • Asm.js的简单介绍
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • es的写入过程
  • Fundebug计费标准解释:事件数是如何定义的?
  • Java小白进阶笔记(3)-初级面向对象
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • passportjs 源码分析
  • Redux 中间件分析
  • SegmentFault 2015 Top Rank
  • 阿里云Kubernetes容器服务上体验Knative
  • 从setTimeout-setInterval看JS线程
  • 大主子表关联的性能优化方法
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 深入浏览器事件循环的本质
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 我是如何设计 Upload 上传组件的
  • 如何用纯 CSS 创作一个货车 loader
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #Lua:Lua调用C++生成的DLL库
  • #pragma 指令
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • $(function(){})与(function($){....})(jQuery)的区别
  • (16)Reactor的测试——响应式Spring的道法术器
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (done) ROC曲线 和 AUC值 分别是什么?
  • (solr系列:一)使用tomcat部署solr服务
  • (八)Flask之app.route装饰器函数的参数
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (初研) Sentence-embedding fine-tune notebook
  • (附源码)php投票系统 毕业设计 121500
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (六)软件测试分工