Luogu P2680 运输计划(二分+树上差分)
题意
题目背景
公元\(2044\)年,人类进入了宇宙纪元。
题目描述
公元\(2044\)年,人类进入了宇宙纪元。
\(L\)国有\(n\)个星球,还有\(n-1\)条双向航道,每条航道建立在两个星球之间,这\(n-1\)条航道连通了\(L\)国的所有星球。
小\(P\)掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从\(u_i\)号星球沿最快的宇航路径飞行到\(v_i\)号星球去。显然,飞船驶过一条航道是需要时间的,对于航道\(j\),任意飞船驶过它所花费的时间为\(t_j\),并且任意两艘飞船之间不会产生任何干扰。
为了鼓励科技创新,\(L\)国国王同意小\(P\)的物流公司参与\(L\)国的航道建设,即允许小\(P\)把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。
在虫洞的建设完成前小\(P\)的物流公司就预接了\(m\)个运输计划。在虫洞建设完成后,这\(m\)个运输计划会同时开始,所有飞船一起出发。当这\(m\)个运输计划都完成时,小\(P\)的物流公司的阶段性工作就完成了。
如果小\(P\)可以自由选择将哪一条航道改造成虫洞,试求出小\(P\)的物流公司完成阶段性工作所需要的最短时间是多少?
输入输出格式
输入格式:
第一行包括两个正整数\(n, m\),表示\(L\)国中星球的数量及小\(P\)公司预接的运输计划的数量,星球从\(1\)到\(n\)编号。
接下来\(n-1\)行描述航道的建设情况,其中第\(i\)行包含三个整数\(a_i,b_i\)和\(t_i\),表示第\(i\)条双向航道修建在\(a_i\)与\(b_i\)两个星球之间,任意飞船驶过它所花费的时间为\(t_i\)。数据保证\(1 \leq a_i,b_i \leq n\)且\(0 \leq t_i \leq 1000\)。
接下来\(m\)行描述运输计划的情况,其中第\(j\)行包含两个正整数\(u_j\)和\(v_j\),表示第\(j\)个运输计划是从\(u_j\)号星球飞往\(v_j\)号星球。数据保证\(1 \leq u_i,v_i \leq n\)。
输出格式:
一个整数,表示小\(P\)的物流公司完成阶段性工作所需要的最短时间。
输入输出样例
输入样例:
6 3
1 2 3
1 6 4
3 1 7
4 3 6
3 5 5
3 6
2 5
4 5
输出样例:
11
说明
所有测试数据的范围和特点如下表所示

思路
树上差分板子题,要不你试试? --logeadd
过了一个月终于把它试出来了...
首先对于答案我们来二分,二分的左区间为\(0\)(当然,最优的左区间并不是\(0\)),有区间为最长的运输计划的长度。
运输区间的长度可以用\(O( \log ^2 n)\)的树链剖分或者\(O( \log n)\)的倍增算法(按照这题的数据强度的话后者显然更可过),可是我们如何判定二分出的答案是否可行呢?
首先处理出长度超过二分答案的边的数量\(sum\),然后从根跑一边\(dfs\),统计每个结点下的每一子树中有多少点在计划中会走到该子树的根结点。如果该值为\(sum\),则用这条边更新最大边权,最后直接看最长计划长度减去最大边权是否小于二分答案即可。
现在又有问题了:如何快速统计呢?这就需要树上差分了。对于每一个计划我们把它看成两个部分:从\(u\)到\(LCA(u,v)\)和从\(LCA(u,v)\)到\(v\),我们再不妨把所有分出的部分都看成向上运输的计划,即把它看成这样的两部分:从\(u\)到\(LCA(u,v)\)和从\(v\)到\(LCA(u,v)\)。然后在树上统计每一结点作为计划开头的次数,记为正数;统计每一结点作为结尾的次数,记为负数。
那么按照上面\(dfs\)的思路,我们就可以这么写:
int dfs2(int now)//先看下面那个函数
{
int re=0;//该结点信息
for(register int i=top[now];i;i=nex[i])
{
if(to[i]==fa[now][0]) continue;
int lzq=dfs2(to[i]);//该结点下的子树信息,
re+=lzq;
if(lzq==sum&&len[i]>tmp) tmp=len[i];//如果刚好有sum条边,更新答案
}
return re+js[now];
}
inline bool check(int now)//二分出的答案为now
{
memset(js,0,sizeof js);//结点作为计划开头的次数计数
tmp=-0x3f3f3f3f,sum=0;//sum记录需要减少时间的计划数量,tmp记录有sum条边同时经过的边的最大长度
for(register int i=0;i<m;i++) if(tim[i]>now) sum++,js[u[i]]++,js[v[i]]++,js[st[i]]-=2;//计数统计
dfs2(1);//开始dfs
return max_time-tmp<=now;//判断最大时间的一个计划的时间是否可减少至now
}
AC代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e5+5;
int n,m,u[MAXN],v[MAXN],st[MAXN],tim[MAXN];
int cnt,top[MAXN],to[MAXN<<1],len[MAXN<<1],nex[MAXN<<1];
int dep[MAXN],dis[MAXN],fa[MAXN][20];
int L,R,ans,max_time,tmp,sum,js[MAXN];
inline int read()
{
int re=0;
char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) re=(re<<3)+(re<<1)+ch-'0',ch=getchar();
return re;
}
void dfs1(int now)
{
for(register int i=1;i<=19;i++) fa[now][i]=fa[fa[now][i-1]][i-1];
for(register int i=top[now];i;i=nex[i])
{
if(to[i]==fa[now][0]) continue;
dis[to[i]]=dis[now]+len[i],dep[to[i]]=dep[now]+1,fa[to[i]][0]=now;
dfs1(to[i]);
}
}
int dfs2(int now)
{
int re=0;
for(register int i=top[now];i;i=nex[i])
{
if(to[i]==fa[now][0]) continue;
int lzq=dfs2(to[i]);
re+=lzq;
if(lzq==sum&&len[i]>tmp) tmp=len[i];
}
return re+js[now];
}
inline int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(register int i=19;i>=0;i--) if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];
if(x==y) return x;
for(register int i=19;i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
inline bool check(int now)
{
memset(js,0,sizeof js);
tmp=-0x3f3f3f3f,sum=0;
for(register int i=0;i<m;i++) if(tim[i]>now) sum++,js[u[i]]++,js[v[i]]++,js[st[i]]-=2;
dfs2(1);
return max_time-tmp<=now;
}
int main()
{
n=read(),m=read();
for(register int i=0;i<n-1;i++)
{
int x=read(),y=read(),z=read();
to[++cnt]=y,len[cnt]=z,nex[cnt]=top[x],top[x]=cnt;
to[++cnt]=x,len[cnt]=z,nex[cnt]=top[y],top[y]=cnt;
}
dep[1]=1;
dfs1(1);
for(register int i=0;i<m;i++)
{
u[i]=read(),v[i]=read(),st[i]=LCA(u[i],v[i]);
tim[i]=dis[u[i]]-dis[st[i]]+dis[v[i]]-dis[st[i]];
if(tim[i]>max_time) max_time=tim[i];
}
L=0,R=max_time;
while(L<=R)
{
int mid=(L+R)>>1;
if(check(mid)) ans=mid,R=mid-1;
else L=mid+1;
}
printf("%d",ans);
return 0;
}
Luogu P2680 运输计划(二分+树上差分)的更多相关文章
- 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)
P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...
- P2680 运输计划 二分+树上差分
又咕咕了几天\(QwQ\) 思路:二分+树上差分 提交:\(\geq5\)次 错因:\(lca\)写错+卡了很久常数(哪位大佬帮我康康,有更好的写法请指出\(QwQ\)) 题解: 我们先将原问题转化为 ...
- [luogu]P2680 运输计划[二分答案][树上差分]
[luogu]P2680 [NOIP2015]运输计划 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n ...
- luogu P2680 运输计划 (二分答案+树上差分)
题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间 ...
- 洛谷P2680 运输计划(树上差分+二分)
传送门 考虑树上乱搞 首先这是满足二分性质的,如果在某个时间可以完成工作那么比他更长的时间肯定也能完成工作 然后考虑二分,设当前答案为$mid$,如果有一条链的长度大于$mid$,那么这条链上必须得删 ...
- BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1930 Solved: 1231[Submit][Statu ...
- NOIP2015Day2T3运输计划(二分+树上差分)
做了这么多NOIPTG的题,这是唯一 一道一眼秒的T3(有时候T2还不会做QAQ)... 题目大意就不说了QWQ 思路大概是:啊最大值最小化,来个二分.检验mid的话,显然就是用最长路径减去所有边权& ...
- 【Luogu】P2680运输计划(树上差分+二分)
题目链接 总体思路……怎么说呢……是个暴力吧…… 首先用倍增预处理出每条路径的长度. 然后按长度把路径排序. 然后二分答案.对于当前答案mid检验,怎么检验呢? 首先差分把所有长度比mid大的链上除了 ...
- P2680 运输计划[二分+LCA+树上差分]
题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间,这 n-1n−1 条航道连通了 LL 国的所有星球. 小 ...
随机推荐
- [AHOI2014/JSOI2014]骑士游戏
题目 思博贪心题写了一个半小时没救了,我也没看出这是一个\(spfa\)来啊 设\(dp_i\)表示彻底干掉第\(i\)只怪物的最小花费,一个非常显然的事情,就是对于\(k_i\)值最小的怪物满足\( ...
- 2019 Multi-University Training Contest 7 Kejin Player Final Exam
Kejin Player 期望DP 题意: 初始等级为1,每一级有四个参数 r , s , x , a . 每一级有一个概率p=r/s花费a的代价升级到下一级,失败可能会倒退到x级 设从 l 到 r ...
- DEDECMS织梦后台更新网站栏目无反应一键更新无响应的解决方法
很多站长朋友反应,经常会遇到DEDECMS织梦后台更新网站栏目无反应和一键更新无响应的问题,这个问题的所在就是在于恢复了数据或者覆盖了织梦后台文件之后,点击一键更新完全没反应,或者生成栏目的时候其他都 ...
- iOS开发系列-NSOperation
概述 NSOperation是基于GCD的封装更加面向对象,在使用上也是有任务跟队列的概念,分别对应两个类NSOperation .NSOperationQueue NSOperation和NSOpe ...
- 在 /proc 里实现文件
所有使用 /proc 的模块应当包含 <linux/proc_fs.h> 来定义正确的函数. 要创建一个只读 /proc 文件, 你的驱动必须实现一个函数来在文件被读时产生数据. 当 某个 ...
- Ip- Linux必学的60个命令
1.作用 ip是iproute2软件包里面的一个强大的网络配置工具,它能够替代一些传统的网络管理工具,例如ifconfig.route等,使用权限为超级用户.几乎所有的Linux发行版本都支持该命令. ...
- 【默默努力】PixelFire
先放下我玩游戏的效果图: 关于游戏最后的结束部分其实我还没有截图,看着挺好看的,后面的效果 再放作者大大的项目地址:https://github.com/panruiplay/PixelFire 接下 ...
- SQFREE - Square-free integers
SQFREE - Square-free integers 求n以内,约数中不包含任意一个平方数的个数,\(n≤10^{14}\). 解 显然为约数计数问题,于是想办法转换为代数问题,不难列出 \[a ...
- 便携版Mysql安装
目录 1.安装 0.Mysql下载地址 1.解压 2.在主目录下新建data和tempData两个文件夹 3.配置环境变量 4.配置my.ini 5.安装服务(管理员模式CMD) 6.清空data文件 ...
- fiddler抓包工具遇到的问题-------502报错
遇到的问题: 打开浏览器,输入本机的虚拟机地址的bugfree,出现无法连接的提示,具体是: [Fiddler] The connection to '192.168.211.128' failed. ...