P2680 运输计划(树上差分+lca+二分)
题目背景
公元 20442044 年,人类进入了宇宙纪元。
题目描述
公元20442044 年,人类进入了宇宙纪元。
L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间,这 n-1n−1 条航道连通了 LL 国的所有星球。
小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要u_iu i号星球沿最快的宇航路径飞行到 v_iv i号星球去。显然,飞船驶过一条航道是需要时间的,对于航道 jj,任意飞船驶过它所花费的时间为 t_jt j,并且任意两艘飞船之间不会产生任何干扰。
为了鼓励科技创新, 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_ia
i
,b
i
和 t_it
i
,表示第 ii 条双向航道修建在 a_ia
i
与 b_ib
i
两个星球之间,任意飞船驶过它所花费的时间为 t_it
i
。数据保证 1 \leq a_i,b_i \leq n1≤a
i
,b
i
≤n 且 0 \leq t_i \leq 10000≤t
i
≤1000。
接下来 mm 行描述运输计划的情况,其中第 jj 行包含两个正整数 u_ju
j
和 v_jv
j
,表示第 jj 个运输计划是从 u_ju
j
号星球飞往 v_jv
j
号星球。数据保证 1 \leq u_i,v_i \leq n1≤u
i
,v
i
≤n
输出格式
一个整数,表示小 PP 的物流公司完成阶段性工作所需要的最短时间。
输入输出样例
输入 #1 复制
6 3
1 2 3
1 6 4
3 1 7
4 3 6
3 5 5
3 6
2 5
4 5
输出 #1 复制
11
说明/提示
所有测试数据的范围和特点如下表所示
求所有边最大值的最小化。这种题一看就是二分。
关于边的差分(如找被所有路径共同覆盖的边
首先我们除了一般的grand,depth等数组以外,多开两个数组:tmp和prev。
tmp用来记录点的出现次数(具体点说实际上记录的是点到其父亲的边的出现次数),prev记录每个点到其父亲的那条边。对于一条起点s,终点t的路径。我们这样处理:
tmp[s]++,tmp[t]++,tmp[LCA(s,t)]-=2。(记住:最后要从所有叶结点把权值向上累加。)以一次操作为例,我们来看看效果(可以画一张图)。首先tmp[s]++,一直推上去到根,这时候s到root的路径访问次数都+1,tmp[t]++后,t到lca路径加了1,s到lca路径加了1,而lca到根的路径加了2。
这时,我们只需要tmp[LCA(s,t)]-=2,推到根,就能把那些多余的路径减掉,达到想要的目的。而这是一次操作,对于很多次操作的话,我们只需要维护tmp,而不必每次更新到根,维护好tmp最后Dfs一遍即可。这时如果tmp[i]==次数的话,说明i到其父亲的边是被所有路径覆盖的。如图
代码如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std;const int maxx=3e5+100;
struct node{int x,y,lca;
}b[maxx];
struct edge{int to,next,val;
}e[maxx<<1];
int head[maxx<<1],temp[maxx],deep[maxx],dp[maxx][26],pre[maxx];
ll dis[maxx];
int n,m,tot,flag;
/*--------------事前准备----------------*/
inline void add(int u,int v,int w)
{e[tot].to=v,e[tot].next=head[u],e[tot].val=w,head[u]=tot++;
}
inline void init()
{for(int i=0;i<=n;i++){for(int j=0;j<=25;j++) dp[i][j]=0;}memset(head,-1,sizeof(head));tot=0;
}
/*-----------dfs-----------*/
inline void dfs(int u,int f)
{deep[u]=deep[f]+1;dp[u][0]=f;for(int i=1;i<=25;i++){if(dp[u][i-1]) dp[u][i]=dp[dp[u][i-1]][i-1];else break;}for(int i=head[u];i!=-1;i=e[i].next){int to=e[i].to,w=e[i].val;if(to==f) continue;dis[to]=dis[u]+w;pre[to]=w;dfs(to,u);}
}
inline int dfs2(int u,int f,int cnt,ll maxn)
{int num=temp[u];for(int i=head[u];i!=-1;i=e[i].next){int to=e[i].to;if(to==f) continue;num+=dfs2(to,u,cnt,maxn);}if(num>=cnt&&pre[u]>=maxn) flag=1;return num;
}
/*-----------lca------------*/
inline int get_lca(int x,int y)
{if(deep[x]<deep[y]) swap(x,y);int tmp=deep[x]-deep[y];for(int i=0;i<=25;i++){if(tmp&(1<<i)) x=dp[x][i];}if(x==y) return x;for(int i=25;i>=0;i--){if(dp[x][i]!=dp[y][i]){x=dp[x][i];y=dp[y][i];}}return dp[x][0];
}
/*--------------二分-------------*/
inline int check(ll x)//二分找出大于这个值的边的条数和最大差值
{ll sum;int cnt=0;ll maxn=0;memset(temp,0,sizeof(temp));for(int i=1;i<=m;i++){sum=dis[b[i].x]+dis[b[i].y]-2*dis[b[i].lca];if(sum>x){cnt++;temp[b[i].x]++,temp[b[i].y]++,temp[b[i].lca]-=2;maxn=max(maxn,sum-x);}}if(cnt==0) return 1;flag=0;dfs2(1,0,cnt,maxn);return flag;
}
int main()
{int x,y,w;ll sum,mid;scanf("%d%d",&n,&m);sum=0;init();for(int i=1;i<n;i++){scanf("%d%d%d",&x,&y,&w);add(x,y,w);add(y,x,w);sum+=w;}deep[0]=dis[1]=0;dfs(1,0);for(int i=1;i<=m;i++){scanf("%d%d",&b[i].x,&b[i].y);b[i].lca=get_lca(b[i].x,b[i].y);}ll l=0,r=sum;ll ans;while(l<=r){mid=(l+r)>>1;if(check(mid)){ans=mid;r=mid-1;}else l=mid+1; }printf("%lld\n",ans);return 0;
}
努力加油a啊,(o)/~
P2680 运输计划(树上差分+lca+二分)相关推荐
- BZOJ 4326 NOIP2015 运输计划(树上差分+LCA+二分答案)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MB Submit: 1388 Solved: 860 [Submit][Stat ...
- 洛谷P2680:运输计划(倍增、二分、树上差分)
传送门 文章目录 题目描述 解析 问题 代码 题目描述 解析 求最大值的最小值 容易想到二分 然后...就没有然后了... 看了题解 学会了一个新技能:树上差分 (其实学长之前好像讲过...) 一般的 ...
- [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告
[NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...
- 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)
[题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...
- luogu P2680 运输计划 (二分答案+树上差分)
题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间 ...
- P2680 运输计划
传送门 十分显然完成工作的时间和航耗时最长的运输计划有关 所以题目意思就是要求最大值最小 所以可以想到二分 把所有大于mid时间的航线打上标记,显然删边只能在所有这些航线的公共路径上 要如何快速打标记 ...
- Distance on the tree(树上倍增+主席树+树上差分+lca)南昌网络赛
题目链接:南昌邀请赛网络赛Distance on the tree 统计一条链上边权小于k的边数. 树上差分,对于边权来说,一条链上的边的条数=sum[x]+sum[y]-2*sum[lca(x,y) ...
- P3128-最大流Max Flow【树上差分,LCA】
正题 题目大意 一棵树 若干条路径,哪个点经过的路径最多,求路径条数. 解题思路 对于每条路径计算一次LCALCALCA,然后树上差分就好了. codecodecode #include<cst ...
- 【codevs4632】【BZOJ4326】运输计划,链剖+二分+差分
传送门1 传送门2 写在前面: 当初洗澡的时候脑补了下这个题,觉得很简单直到看到题面,才发现自己记错了,自此开始不归路 思路:这里的链剖实际上就是求每个操作的路径长度(也可以LCA求),然后我想到了二 ...
最新文章
- 读书笔记 《Perl语言入门》 Day 1
- C++ Primer 5th笔记(chap 16 模板和泛型编程)包扩展
- 【华为云技术分享】【测试微课堂】 有的放矢制定测试计划
- Disconnected from the target VM, address:xxxx 或者 Process finished with exit code 1 终极解决办法 idea
- sql 2000 无法连接远程数据库 sqlserver不存在或访问被拒绝、不能打开到主机的连接,在端口1433:连接失败等 解决方案
- linux十分钟调度一次,linux系统任务调度命令crontab
- python能做什么工作-学完Python我们可以做什么工作?
- python opencv 利用 GrabCut 算法(opencv已经实现)从图像中分离出前景
- NVIDIA驱动本来好好的,过几天就无法连接NVIDIA,出现NVIDIA-SMI has failed because it couldn’t communicate with the NVIDIA
- Git-版本控制 (二)
- Fl Studio真的不如Cubase或者Logic Pro等电音软件专业吗?
- 请确保dx环境安装正常后进行开播_虎牙直播助手常见问题汇总
- android adb shell chmod,adb shell 修改用户权限 删除App
- 计算机系统动态库修复,无法定位程序输入点于动态链接库修复解决方法 | 专业网吧维护...
- 编程实现英语句子反转python_Python字符串处理实现单词反转
- NOIP2017 普及 luogu3957 跳房子
- java chmod 777_java中 执行shell中的chmod 777命令,出现Caused by: java.io.IOException: Permission denied???...
- 拿下 ACM 金牌!
- 苹果6访问限制密码4位_苹果ios签名:AppleID为什么开启双重认证那么重要
- java中的Int范围
热门文章
- java ready()_Java.io.BufferedReader.ready()方法实例
- redisson 看门狗_Redisson的分布式锁
- git:The authenticity of host 'github.com (13.250.177.223)' can't be established.
- python分布式爬虫系统_三种分布式爬虫系统的架构方式
- python selenium_Python+selenium自动化测试
- linux添加静态网关route文件,详解Linux系统中配置静态路由的方法
- html 页面跳转 中文传值,两html页面之间的传值,并解决中文乱码问题
- quill鼠标悬浮 出现提示_外设报道——DELUX多彩M618X垂直鼠标颠覆创新
- 文件夹里面照片自动分成子文件夹_Windows居然自带这个功能,自动整理你硬盘里的照片...
- std::async()详解