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

请注意常数因子带来的程序效率上的影响。
这道题有点东西。本来是想练手树上差分的,发现很多题解都是用二分+树链剖分写的,看了一下,树链剖分、线段树、树状数组(求线段标记次数)、LCA(有的是用tarjan求的路径的长度)。
一开始我看到这道题的时候,看到所有的计划都一起跑,就有点傻了,一起跑可怎么找,感觉直接暴力找回超时,后来算了一下,好像可以过。
我的思路就是:一开始的时候,先把所有的路径的长度出来,然后通过dfs把lca的相关东西处理出来,每一条线段的长度先保存一下,然后二分,最长的路径长度为右端点r,二分,每二分一次就遍历一下所有的路径,大于mid长度的,就树上差分保存一下,然后dfs一下就把所有的线段的标记次数找出来了,然后找一下是不是有某条线段被标记的次数为加入的路径的数量,如果有,就说明删掉这条边是可能成立的,最长的路径-这条线段与mid比较一下就可以了,有一点就是标记的次数相同的找最长的那条线段,一开始智障,找到了就跳出去了,wa了。。。
还有一点就是存边的时候数组开二倍,还有一点就是每一条线段的长度保存的时候,不能直接在输入的时候保存,这样会wa,因为用大的数当边的编号是对的,假设1和5相连,5和3相连,一开始1和5相连长度为3,输入的时候,我存的是vv[5]=3;但是等到我存5和3长度为5的时候,vv[5]=5,就不对了。soga,嘎嘎。
测评姬有点情绪不稳,相同的代码我第一次交有一个样例点tle,再交一次一模一样的,过了。。。试了好几次,网卡的时候就容易tle。。。
代码:
//洛谷 P2680 运输计划 二分+树上差分(边覆盖)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long ll;
const int maxn=3e5+; struct node{
int to,val,next;
}edge[maxn<<]; int p1[maxn],p2[maxn],vv[maxn],maxx=,ret,num,n,m,cnt,ans;
int head[maxn<<],sum[maxn],dep[maxn],fa[maxn][],dis[maxn],len[maxn]; void add(int x,int y,int v){edge[++cnt].to=y,edge[cnt].val=v,edge[cnt].next=head[x],head[x]=cnt;} void dfs(int u,int fath)
{
dep[u]=dep[fath]+,fa[u][]=fath;
for(int i=;fa[u][i];++i) fa[u][i+]=fa[fa[u][i]][i];
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to,w=edge[i].val;
if(v!=fath) dis[v]=dis[u]+w,vv[v]=w,dfs(v,u);//vv的dfs一开始写挫了,直接写到输入那里了
}
} int LCA(int u,int v)
{
if(dep[u]>dep[v]) swap(u,v);
for(int i=;i>=;i--) if(dep[u]<=dep[v]-(<<i)) v=fa[v][i];
if(u==v) return u;
for(int i=;i>=;i--) if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
return fa[u][];
} void Dfs(int u,int fath)//标记之后的Dfs
{
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==fath) continue;
Dfs(v,u);
sum[u]+=sum[v];
}
if(num==sum[u]){//如果标记的次数正好为加的边的数量,说明这一段在所有边上都有
ret=max(ret,vv[u]);//标记次数相同的找长度最大的
}
} bool pig(int h)//判断
{
num=;ret=; memset(sum,,sizeof(sum));
for(int i=;i<=m;i++){
if(len[i]>h){
num++;int lca=LCA(p1[i],p2[i]);
sum[p1[i]]++;sum[p2[i]]++;sum[lca]-=;
}
}
if(!num) return ;
Dfs(,);return maxx-ret<=h;
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);add(v,u,w);//vv[max(u,v)]=w;
}
dfs(,);
for(int i=;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
p1[i]=min(x,y);p2[i]=max(x,y);
int lca=LCA(x,y);
len[i]=dis[x]+dis[y]-*dis[lca];
maxx=max(maxx,len[i]);
}
int l=,r=maxx;
while(l<=r){
int mid=(l+r)>>;//cout<<"mid= "<<mid<<endl;
if(pig(mid))
r=mid-;
else
l=mid+;
}
cout<<l<<endl; }
/*
6 3
1 2 3
1 6 4
1 3 7
3 4 6
3 5 5
3 6
2 5
4 5 11 */
不开心,最近状态不好,铁了一年了。唉,菜是原罪。
洛谷 P2680 运输计划-二分+树上差分(边权覆盖)的更多相关文章
- 洛谷P2680 运输计划(树上差分+二分)
传送门 考虑树上乱搞 首先这是满足二分性质的,如果在某个时间可以完成工作那么比他更长的时间肯定也能完成工作 然后考虑二分,设当前答案为$mid$,如果有一条链的长度大于$mid$,那么这条链上必须得删 ...
- Luogu P2680 运输计划(二分+树上差分)
P2680 运输计划 题意 题目背景 公元\(2044\)年,人类进入了宇宙纪元. 题目描述 公元\(2044\)年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道 ...
- P2680 运输计划 二分+树上差分
又咕咕了几天\(QwQ\) 思路:二分+树上差分 提交:\(\geq5\)次 错因:\(lca\)写错+卡了很久常数(哪位大佬帮我康康,有更好的写法请指出\(QwQ\)) 题解: 我们先将原问题转化为 ...
- 洛谷 P2680 运输计划 解题报告
P2680 运输计划 题目背景 公元2044年,人类进入了宇宙纪元. 题目描述 公元2044年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道,每条航道建立在两个星 ...
- 洛谷P2680 运输计划
大概就是二分+树上差分... 题意:给你树上m条路径,你要把一条边权变为0,使最长的路径最短. 最大的最小,看出二分(事实上我并没有看出来...) 然后二分k,对于所有大于k的边,树上差分求出最长公共 ...
- 洛谷P2680 运输计划 [LCA,树上差分,二分答案]
题目传送门 运输计划 Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n?1 条双向航道,每条航道建立在两个星球之间, 这 n?1 条航道连通了 L 国的所 ...
- 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)
[题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...
- 洛谷P2680 运输计划——树上差分
题目:https://www.luogu.org/problemnew/show/P2680 久违地1A了好高兴啊! 首先,要最大值最小,很容易想到二分: 判断当前的 mid 是否可行,需要看看有没有 ...
- BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1930 Solved: 1231[Submit][Statu ...
随机推荐
- C语言双链表遍历,插入,删除
#include<stdio.h> #include<stdlib.h> #include <string.h> #define bzero(a, b) memse ...
- emqtt新版升级一些事项和操作
注解 Erlang/OTP R19依赖lksctp-tools库 yum install lksctp-tools 控制台地址: http://127.0.0.1:18083,默认用户: admin, ...
- git代码冲突
如果系统中有一些配置文件在服务器上做了配置修改,然后后续开发又新添加一些配置项的时候, 在发布这个配置文件的时候,会发生代码冲突: error: Your local changes to the f ...
- generatorConfiguration配置文件及其详细解读
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE generatorConfiguratio ...
- iOS Button设置
UIButton *kefuBtn = [[UIButton alloc]initWithFrame:CGRectMake(, , , )]; kefuBtn.backgroundColor = SX ...
- [uva11174]村民排队 递推+组合数+线性求逆元
n(n<=40000)个村民排成一列,每个人不能排在自己父亲的前面,有些人的父亲不一定在.问有多少种方案. 父子关系组成一个森林,加一个虚拟根rt,转化成一棵树. 假设f[i]表示以i为根的子树 ...
- POJ3495 Bitwise XOR of Arithmetic Progression
Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 772 Accepted: 175 Description Write ...
- elementui table 多选 获取id
//多选相关方法 toggleSelection(rows) { if (rows) { rows.forEach(row => { this.$refs.multipleTable.toggl ...
- vue双向绑定原理源码解析
当我们学习angular或者vue的时候,其双向绑定为我们开发带来了诸多便捷,今天我们就来分析一下vue双向绑定的原理. 简易vue源码地址:https://github.com/maxlove123 ...
- 我的spring boot,杨帆、起航!
快速新建一个spring boot工程可以去http://start.spring.io/这个网址,配置完后会自动下载一个工程的压缩包,解压后导入相关ide工具即可使用. 工程中会自带一个class启 ...