题解 [NOIP2015]运输计划

题面

解析

首先肯定是要求出每条路径的长度.

这个用节点到根的前缀和就行了(一开始脑抽写了个线段树...)

然后有一个显然的类似贪心的想法,

就是你改造的边肯定在最长的路径上,

(不然没有*用)

那么考虑枚举最长的路径上的边,计算改造它的答案,

对于边\(x\),路径可以分为两类:经过它的和不经过它的.

在它被改造后,经过它的路径就都减少了它的长度,

于是最长的就还是这条最长的路径,

而没经过它的就没有受到影响,取最长的路径,

因此删掉\(x\)的答案就是上面两种情况的\(max\),

但关键就是怎么求第二种情况:没经过\(x\)的最长的路径.

枚举边再一个个求似乎不可行,

我们可以考虑枚举路径计算它对边的贡献,

显然没在这条路径上的边都可以被这条路径更新,

于是考虑树剖,

这样一条路径就被划分成了若干个区间,

而区间的补集就是它要更新的边,

把边的答案对应到深度较大的点上,用线段树维护最大值即可.

code(代码挺长但仔细康康应该能懂):

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fot for
#define ls(a) a<<1
#define rs(a) a<<1|1
#define fre(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
using namespace std; inline int read(){
int sum=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return f*sum;
} const int N=3000005;
struct ques{int s,t,w;}q[N];
struct edge{int to,next,w;}e[N<<1];
struct tree{int l,r,sum,maxn,tag;}t[N<<1];
struct qujian{int l,r;}sta[N];
struct node{int size,son,id,fa,dep,top,val;}a[N];
int n,m,tot,pla[N],ans;
int head[N],cnt,s[N]; inline void add(int x,int y,int w){
e[++cnt]=(edge){head[x],y,w};head[x]=cnt;
} inline void dfs1(int x,int fa){
a[x].size=1;a[x].fa=fa;
a[x].dep=a[fa].dep+1;
for(int i=head[x];i;i=e[i].to){
int k=e[i].next;
if(k==fa) continue;
s[k]=s[x]+e[i].w;
dfs1(k,x);a[k].val=e[i].w;
a[x].size+=a[k].size;
if(a[k].size>a[a[x].son].size) a[x].son=k;
}
} inline void dfs2(int x,int top){
a[x].top=top;a[x].id=++tot;
pla[tot]=x;
if(a[x].son) dfs2(a[x].son,top);
for(int i=head[x];i;i=e[i].to){
int k=e[i].next;
if(k==a[x].fa||k==a[x].son) continue;
dfs2(k,k);
}
} inline void build(int p,int l,int r){
t[p].l=l;t[p].r=r;
if(l==r) {t[p].sum=a[pla[l]].val;return ;}
int mid=(l+r)>>1;
build(ls(p),l,mid);build(rs(p),mid+1,r);
} inline int lca(int x,int y){
while(a[x].top!=a[y].top){
if(a[a[x].top].dep<a[a[y].top].dep) swap(x,y);
x=a[a[x].top].fa;
}
if(a[x].dep>a[y].dep) swap(x,y);
return x;
} inline int dis(int x,int y){
return s[x]+s[y]-2*s[lca(x,y)];
} inline bool cmp(ques a,ques b){return a.w>b.w;} inline void Pushup(int p){
t[p].maxn=max(t[ls(p)].maxn,t[rs(p)].maxn);
} inline void Pushdown(int p){
int ret=t[p].tag;
t[ls(p)].tag=max(t[ls(p)].tag,ret);
t[rs(p)].tag=max(t[rs(p)].tag,ret);
t[ls(p)].maxn=max(t[ls(p)].maxn,ret);
t[rs(p)].maxn=max(t[rs(p)].maxn,ret);
} inline void change(int p,int l,int r,int w){
if(l>r||!l||!r) return ;
if(t[p].l>=l&&t[p].r<=r){
t[p].maxn=max(t[p].maxn,w);
t[p].tag=max(t[p].tag,w);
return ;
}
Pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
if(l<=mid) change(ls(p),l,r,w);
if(r>mid) change(rs(p),l,r,w);
Pushup(p);
} inline bool cmp1(qujian a,qujian b){return a.l<b.l;} inline void find(int x,int y,int w){
int top=0;
while(a[x].top!=a[y].top){
if(a[a[x].top].dep<a[a[y].top].dep) swap(x,y);
sta[++top]=(qujian){a[a[x].top].id,a[x].id};
x=a[a[x].top].fa;
}
if(a[x].dep>a[y].dep) swap(x,y);
sta[++top]=(qujian){a[x].id+1,a[y].id};
int L=1,R;
sort(sta+1,sta+top+1,cmp1);
for(int i=1;i<=top;i++){
R=sta[i].l-1;
change(1,L,R,w);
L=sta[i].r+1;
}
change(1,L,n,w);
} inline int search(int p,int x){
if(t[p].l==t[p].r) return t[p].maxn;
Pushdown(p);
int mid=(t[p].l+t[p].r)>>1;
if(x<=mid) return search(ls(p),x);
else return search(rs(p),x);
} inline void solve(int x,int y){
int pp=lca(x,y);
while(x!=pp){
ans=min(ans,max(q[1].w-a[x].val,search(1,a[x].id)));
x=a[x].fa;
}
while(y!=pp){
ans=min(ans,max(q[1].w-a[y].val,search(1,a[y].id)));
y=a[y].fa;
}
} signed main(){
n=read();m=read();
for(int i=1;i<n;i++){
int x=read(),y=read(),w=read();
add(x,y,w);add(y,x,w);
}
for(int i=1;i<=m;i++){
q[i].s=read(),q[i].t=read();
}
dfs1(1,0);dfs2(1,1);
build(1,1,n);
for(int i=1;i<=m;i++){
q[i].w=dis(q[i].s,q[i].t);
}
for(int i=1;i<=m;i++) find(q[i].s,q[i].t,q[i].w);
sort(q+1,q+m+1,cmp);
ans=q[1].w;
fot(int i=1;i<=m;i++)
if(q[i].w==q[1].w) solve(q[i].s,q[i].t);
else break;
printf("%d\n",ans);
return 0;
}

题解 [NOIP2015]运输计划的更多相关文章

  1. NOIP2015 运输计划(bzoj4326)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 886  Solved: 574[Submit][Status] ...

  2. [BZOJ4326][codevs4632][codevs5440][UOJ#150][NOIP2015]运输计划

    [BZOJ4326][codevs4632][codevs5440][UOJ#150][NOIP2015]运输计划 试题描述 公元 2044 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n− ...

  3. [NOIP2015]运输计划 D2 T3 LCA+二分答案+差分数组

    [NOIP2015]运输计划 D2 T3 Description 公元2044年,人类进入了宇宙纪元. L国有n个星球,还有n-1条双向航道,每条航道建立在两个星球之间,这n-1条航道连通了L国的所有 ...

  4. bzoj 4326: NOIP2015 运输计划

    4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MB Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个 ...

  5. NOIP2015 运输计划(二分+LCA+差分)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 308  Solved: 208[Submit][Status] ...

  6. 数据结构(树链剖分):COGS 2109. [NOIP2015] 运输计划

    2109. [NOIP2015] 运输计划 ★★★   输入文件:transport.in   输出文件:transport.out   简单对比时间限制:1 s   内存限制:256 MB [题目描 ...

  7. BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1930  Solved: 1231[Submit][Statu ...

  8. cogs2109 [NOIP2015] 运输计划

    cogs2109 [NOIP2015] 运输计划 二分答案+树上差分. STO链剖巨佬们我不会(太虚伪了吧 首先二分一个答案,下界为0,上界为max{路径长度}. 然后判断一个答案是否可行,这里用到树 ...

  9. LOJ2425 NOIP2015 运输计划 【二分+LCA+树上差分】*

    LOJ2425 NOIP2015 运输计划 LINK 题意:给你一颗树,可以将任意一条边的权值变成0,然后求m条路径的长度的最小值 思路: 先二分最后的距离ans,然后我们把路程大于ans的所有路径拿 ...

随机推荐

  1. Java:HashMap的实现原理(JDK1.8)

    1.    HashMap概述: HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变 ...

  2. 【坑】springMvc 信息校验,读取不到错误配置信息的问题

    文章目录 前言 ResourceBundleMessageSource 后记 前言 springMvc 的一大利器,validation 检验,通过注解,可以帮我们完成校验,很是顺手. 终极偷懒检验, ...

  3. 【坑】mysql 8.0以后的驱动 jar、连接池的变化

    文章目录 前言 com.mysql.cj.jdbc.Driver 后记 前言 博主公司刚配置了新电脑,安装开发环境的时候,美滋滋的将开发工具都装了新版本,结果在使用 mysql 的时候,发现一直链接数 ...

  4. 谈谈Python中pop与remove的用法

    remove() 函数用于移除列表中某个值的第一个匹配项. remove()方法语法:  list.remove(obj) 如果obj不在列表中会引发 ValueError 错误,通常先使用count ...

  5. SAS学习笔记22 t检验、卡方检验

  6. odoo——日历的一对多与多对一

    # model文件 # -*- coding: utf-8 -*- from odoo import api, fields, models class TodoTestYear(models.Mod ...

  7. Idea中一个服务按多个端口同时启动

    1.勾选并行启动 2.-Dserver.port=9018

  8. (二十八)jsp之EL表达式

    一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...

  9. 在.netcore webapi项目中使用后台任务工具Hangfire

    安装Hangfire 在webapi项目中通过nuget安装Hangfire.Core,Hangfire.SqlServer,Hangfire.AspNetCore,截止到目前的最新版本是1.7.6. ...

  10. wepy全局拦截器

    wepy有支持全局拦截器,但是请求需要使用wepy.request().then(): 在app.wpy文件中配置以下内容,与data同级 constructor(){ super(); this.u ...