题解 [NOIP2015]运输计划
题解 [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]运输计划的更多相关文章
- NOIP2015 运输计划(bzoj4326)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 886 Solved: 574[Submit][Status] ...
- [BZOJ4326][codevs4632][codevs5440][UOJ#150][NOIP2015]运输计划
[BZOJ4326][codevs4632][codevs5440][UOJ#150][NOIP2015]运输计划 试题描述 公元 2044 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n− ...
- [NOIP2015]运输计划 D2 T3 LCA+二分答案+差分数组
[NOIP2015]运输计划 D2 T3 Description 公元2044年,人类进入了宇宙纪元. L国有n个星球,还有n-1条双向航道,每条航道建立在两个星球之间,这n-1条航道连通了L国的所有 ...
- bzoj 4326: NOIP2015 运输计划
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MB Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个 ...
- NOIP2015 运输计划(二分+LCA+差分)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 308 Solved: 208[Submit][Status] ...
- 数据结构(树链剖分):COGS 2109. [NOIP2015] 运输计划
2109. [NOIP2015] 运输计划 ★★★ 输入文件:transport.in 输出文件:transport.out 简单对比时间限制:1 s 内存限制:256 MB [题目描 ...
- BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1930 Solved: 1231[Submit][Statu ...
- cogs2109 [NOIP2015] 运输计划
cogs2109 [NOIP2015] 运输计划 二分答案+树上差分. STO链剖巨佬们我不会(太虚伪了吧 首先二分一个答案,下界为0,上界为max{路径长度}. 然后判断一个答案是否可行,这里用到树 ...
- LOJ2425 NOIP2015 运输计划 【二分+LCA+树上差分】*
LOJ2425 NOIP2015 运输计划 LINK 题意:给你一颗树,可以将任意一条边的权值变成0,然后求m条路径的长度的最小值 思路: 先二分最后的距离ans,然后我们把路程大于ans的所有路径拿 ...
随机推荐
- TCP状态转换(图解+文字解说)
<深入分析 javaweb 技术内幕>P38 读书扩展 作者:淮左白衣 写于2018年4月12日20:58:36 目录 TCP状态转换图解 图解三次握手 文字讲解三次握手: 图解四次挥手 ...
- EXIT(外部中断)控制实验
实验目的 设计使用外接的按键来作为触发源,使得控制器产生中断,并在中断服务函数中实现控制小灯的亮灭. 按键硬件点路 编程要点 初始化用来产生中断的 GPIO: 初始化 EXTI: 配置 NVIC: 编 ...
- jacascript 基础数据类型(一)
前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! 数据类型有 number.boolean.string.object.null.undefined; un ...
- poj 2406 求最短重复字串
题解: KMP中next数组的巧妙运用.在这里我们假设这个字符串的长度是len,那么如果len可以被len-next[len]整除的话,我们就可以说len-next[len]就是那个最短子串的长度为什 ...
- hdu 2089 入手数位dp问题
数位dp解决的问题是指求在一段数的区间里面 满足条件的数的个数 核心为两点 http://wenku.baidu.com/link?url=tpfIYzhx_MzevpIM58UZ66pr-87MCF ...
- CAS 5.x搭建常见问题系列(2).PKIX path building failed
错误原因 服务端的证书是不安全的,Cas的客户端在调用时因为安全提醒造成调用失败. CAS的客户端需要导入服务端的证书后,就正常了. 具体操作步骤如下: 1. 首先启动tomcat,看下之前搭建的ca ...
- B+Tree的基本介绍
概念 特点 B-Tree有许多变种,其中最常见的是B+Tree,例如MySQL就普遍使用B+Tree实现其索引结构. 与B-Tree相比,B+Tree有以下不同点: 每个节点的指针上限为2d而不是2d ...
- node 和 postgres
安装 npm i pg ,如果慢的话,记得爬梯子 连接池的方式: var pg = require('pg'); // 数据库配置 var config = { user:"postgres ...
- siamese跟踪论文思考
转载自:https://zhuanlan.zhihu.com/p/34222060 通过作者在专栏里面放的几张响应图我们可以看到:SiamFC并不能区分不同的物体,图片上所有具有语义信息的物体都会得到 ...
- VBA连接操作符
VBA支持以下连接运算符. 假设变量A=5,变量B=10,则 - 运算符 描述 示例 + 将两个值添加为变量,其值是数字 A + B = 15 & 连接两个值 A & B = 510 ...