#LCA,二分,树上差分#洛谷 2680 运输计划
题目
一棵树,每条边上都有边权,现在选择一条边将边权变为0,使\(m\)条路径边权和其中一条的最大值最小,问这个值
分析
由于大于最终结果的一定可行,小于最终结果的一定不可行,所以二分答案,首先答案以下的需求都不需要考虑,差分,如果该位置上的需求数量等于所需求的数量那么这条边就可以选,但是如果最大值减去这条边仍不能小于等于答案,那么依然是不可行的,或者不可能达到需求数量也是不可行的
代码
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define rr register
using namespace std;
const int N=300011;
struct node{int y,w,next;}e[N<<1];
struct rec{int x,y,Lca,w;}q[N];
int dep[N],fat[N],son[N],big[N],top[N],n,k=1,m,tot,ls[N],w[N],mx,dis[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
bool cmp(const rec &a,const rec &b){return a.w>b.w;}
inline signed max(int a,int b){return a>b?a:b;}
inline void dfs1(int x,int fa){
dep[x]=dep[fa]+1,fat[x]=fa,son[x]=1;
for (rr int i=ls[x],mson=-1;i;i=e[i].next)
if (e[i].y!=fa){
dis[e[i].y]=dis[x]+e[i].w,dfs1(e[i].y,x),son[x]+=son[e[i].y];
if (son[e[i].y]>mson) big[x]=e[i].y,mson=son[e[i].y];
}
}
inline void dfs2(int x,int linp){
top[x]=linp; if (!big[x]) return; dfs2(big[x],linp);
for (rr int i=ls[x];i;i=e[i].next)
if (e[i].y!=fat[x]&&e[i].y!=big[x]) dfs2(e[i].y,e[i].y);
}
inline signed lca(int x,int y){
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) x^=y,y^=x,x^=y;
x=fat[top[x]];
}
if (dep[x]>dep[y]) x^=y,y^=x,x^=y;
return x;
}
inline void dfs3(int x,int fa){
for (rr int i=ls[x];i;i=e[i].next)
if (e[i].y!=fa) dfs3(e[i].y,x),w[x]+=w[e[i].y];
if (w[x]==tot) mx=max(mx,dis[x]-dis[fat[x]]);
}
inline bool check(int now){
memset(w,0,sizeof(w)),tot=0,mx=-4e8;
for (rr int i=1;i<=m&&q[i].w>now;++i)
++tot,++w[q[i].x],++w[q[i].y],w[q[i].Lca]-=2;
dfs3(1,0);
if (mx==-4e8||q[1].w-mx>now) return 0;
else return 1;
}
signed main(){
n=iut(); m=iut();
for (rr int i=1;i<n;++i){
rr int x=iut(),y=iut(),w=iut();
e[++k]=(node){y,w,ls[x]},ls[x]=k,
e[++k]=(node){x,w,ls[y]},ls[y]=k;
}
dfs1(1,0),dfs2(1,0); rr int l=0,r=-4e8;
for (rr int i=1;i<=m;++i){
q[i].x=iut(),q[i].y=iut(),q[i].Lca=lca(q[i].x,q[i].y),
q[i].w=dis[q[i].x]+dis[q[i].y]-2*dis[q[i].Lca],r=max(r,q[i].w);
}
sort(q+1,q+1+m,cmp);
while (l<r){
rr int mid=(l+r)>>1;
if (check(mid)) r=mid;
else l=mid+1;
}
return !printf("%d",l);
}
------------恢复内容结束------------
#LCA,二分,树上差分#洛谷 2680 运输计划的更多相关文章
- BZOJ4326或洛谷2680 运输计划
BZOJ原题链接 洛谷原题链接 用\(LCA\)初始化出所有运输计划的原始时间,因为答案有单调性,所以二分答案,然后考虑检验答案. 很容易想到将所有超出当前二分的答案的运输计划所经过的路径标记,在这些 ...
- 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)
P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...
- 洛谷P2680 运输计划
大概就是二分+树上差分... 题意:给你树上m条路径,你要把一条边权变为0,使最长的路径最短. 最大的最小,看出二分(事实上我并没有看出来...) 然后二分k,对于所有大于k的边,树上差分求出最长公共 ...
- 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)
[题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...
- 洛谷P2680 运输计划 [LCA,树上差分,二分答案]
题目传送门 运输计划 Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n?1 条双向航道,每条航道建立在两个星球之间, 这 n?1 条航道连通了 L 国的所 ...
- 洛谷P2680 运输计划(树上差分+二分)
传送门 考虑树上乱搞 首先这是满足二分性质的,如果在某个时间可以完成工作那么比他更长的时间肯定也能完成工作 然后考虑二分,设当前答案为$mid$,如果有一条链的长度大于$mid$,那么这条链上必须得删 ...
- [luogu2680] 运输计划 (lca+二分+树上差分)
传送门 Description Input Output 一个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间. Sample Input 6 3 1 2 3 1 6 4 3 1 7 4 3 ...
- 洛谷P2680 运输计划——树上差分
题目:https://www.luogu.org/problemnew/show/P2680 久违地1A了好高兴啊! 首先,要最大值最小,很容易想到二分: 判断当前的 mid 是否可行,需要看看有没有 ...
- 【学术篇】树上差分--洛谷3128最大流Max Flow
懒得贴题目,直接放不稳定的传送门(雾):点击前往暴风城(雾) 据说这题是BZOJ3490,但本蒟蒻没有权限╮(╯_╰)╭ 这题似乎就是裸树上差分... 对于树上(x,y)之间的路径上的点区间c[i]加 ...
- 洛谷 P2680 运输计划 解题报告
P2680 运输计划 题目背景 公元2044年,人类进入了宇宙纪元. 题目描述 公元2044年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道,每条航道建立在两个星 ...
随机推荐
- 【Android 逆向】【ARM汇编】 堆栈
arm 四种栈 1 空栈 栈指针指向空位,每次存入时可以直接存入然后栈指针移动一格:而取出时需要先移动一格才能取出 2 满栈 栈指针指向栈中最后一格数据.每次存入时需要先移动栈指针一格再存入.取出时可 ...
- 【Filament】Filament环境搭建
1 前言 Filament 是一个实时物理渲染引擎,用于 Android.iOS.Linux.macOS.Windows 和 WebGL 平台.该引擎旨在提供高效.实时的图形渲染,并被设计为在 A ...
- Isito 入门(二):Istio 的部署
本教程已加入 Istio 系列:https://istio.whuanle.cn 目录 2,部署 Istio 安装 Helm 部署 istio-base 部署 istiod 部署 istio-ingr ...
- 代码随想录算法训练营第十三天| 239. 滑动窗口最大值 347.前 K 个高频元素 总结
239. 滑动窗口最大值 (一刷至少需要理解思路) 卡哥建议:之前讲的都是栈的应用,这次该是队列的应用了.本题算比较有难度的,需要自己去构造单调队列,建议先看视频来理解. 题目链接/文章讲解/视频讲解 ...
- C++ //常用查找算法 find_if
1 //常用查找算法 find_if 2 #include<iostream> 3 #include<string> 4 #include<vector> 5 #i ...
- harbor 安装
下载地址: https://github.com/goharbor/harbor/releases?page=1 下载了多个版本,发现仅v1.10.17版本支持GC清理,所以这里安装的v1.10.17 ...
- Learning by teaching --- 费曼学习法
世界上存在成千上万种学习法,如果上天只让我掌握一种,那一定就是"费曼学习法". 介绍 费曼学习法是由诺贝尔物理学奖获得者理查德·费曼提出的一种学习方法,其核心思想是将所学内容用自己 ...
- zookeeper源码(10)node增删改查及监听
本文将从leader处理器入手,详细分析node的增删改查流程及监听器原理. 回顾数据读写流程 leader ZookeeperServer.processPacket封装Request并提交给业务处 ...
- [VueJsDev] 快速入门 - vscode 设置推荐
[VueJsDev] 目录列表 https://www.cnblogs.com/pengchenggang/p/17037320.html vscode设置推荐 ::: details 目录 目录 v ...
- isNumber 数字正则校验 表达式
isNumber 数字正则校验 表达式 isNumber(value) { return (/(^-?[0-9]+\.{1}\d+$)|(^-?[1-9][0-9]*$)|(^-?0{1}$)/).t ...