运输计划[做题笔记]



挺难绷的。。。

题意

概括:给定 \(n\) 个节点的树和 \(n-1\) 条边的权值,现在可以将一条边的权值改为 \(0\) 。找出一条边,使得将这条边权值赋为 \(0\) 时,\(T\) 组节点 \(u,v\) 之间的距离最大值最小,输出最小值。

思路分析

一开始想假了,天真的以为被 \(T\) 组节点 \(u,v\) 覆盖的次数最多,且权值较大的边就是要删去的边,\(38\)分,查题解才知道是二分答案。

不过确实,求最大值最小,的确是要二分的。若 \(t1<t2\) ,且 \(t1\) 合法,那么\(t2\)当然合法,单调性不就出来了?明确要二分后,先预处理出 \(T\) 组节点 \(u,v\) 的 \(LCA\) 和距离 \(len\) ,那么答案二分的区间就是 \([0,MAXLEN]\) 。

    二分答案的精髓是什么?是check()函数
————miaomiao

首先为了不产生歧义,我们定义节点\(u,v\)之间的树上路径为链,路径长为链长;下文的边即为树的边。

那么,对于当前 \(check\) 的 \(x\),有:

  • \(First\),要使 \(x\) 合法,那么删去这条边后,所有链长均小于等于 \(x\)
  • \(Second\),要找出这条边,首先要枚举所有的链长 \(len\) ,记录比\(x\)大的个数 \(sum\) ,并将这些链在树上差分。如果有一条边被上述链同时覆盖,显然这就是我们要赋\(0\)的最优边(当然可能存在多条,显然要取边权最大的 \(max\_ len\))
  • \(Third\),用 \(MAXLEN-max\_ len\),这是赋\(0\)后的最长链的长,如果结果\(<=x\),显然\(x\)合法(最长边都满足,底下那些小弟就更不用说了)

嗯,一切都这么美妙,但如果不会树上差分,不就祭了?那么,首先我们要会正常的差分 (不会建议回普及组重修),说白了差分就是一个反映相对大小的东西

如果你觉得一个知识点很简单,下一步,把它挂到树上去。
————波波

定义一个差分数组 \(spx[\ ]\) 。对于这种求边被覆盖的次数,首先边权肯定都是\(0\),边上差分很不方便,那么我们把边权下放到点上,\(spx_i\) 表示 \(i\) 和 \(i\) 的父节点之间的边的差分,当我们要将 \(u_i,v_i\) 这条链放到覆盖到树上,显然我们只需要修改 \(u_i\) 节点, \(v_i\) 节点和 \(LCA(u_i,v_i)\) 的差分,\(spx[u_i]\)++, \(spx[v_i]\)++, \(spx[lca(u_i,v_i)]\)-=\(2\)。为啥是\(2\)?很显然我们将链 \((u_i,v_i)\) 分成了 \((u_i,lca_i)\) 和 \((v_i,lca_i)\) 两条链进行差分,显然要减\(2\)。

差分完之后,实际的边权\(k\)就是它的子树中差分数组的和(类似于正常差分中前缀和),这可以通过一遍\(dfs\)实现。

服了,求\(LCA\)必须用\(tarjan\),倍增过不了,卡\(95\)……挺难崩的,现学\(tarjan\)求\(LCA\)(狂\(D\)不止)不过\(tarjan\)求确实比倍增快,\(O(n+m)\) 比 \(O(n\ log_2n)\) 友好多了

呃,如果有dalao发现我的代码和您差不多,那我可能是贺的您的,别D我(逃,%%%

\(AC \ code\)

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define N 300010
#define int long long
int n,m;int ans;
struct EDGE{
int next,to,t;
}e[N<<1],d[N<<1];//q是存原树,d是存查询的T组u,v构成的树,为了tarjan求LCA而生
int spx[N];//这是差分数组,数组名只是数组名,没啥特殊含义
int he[N],tot;
int hd[N];
int edge[N];//树上差分,将边权下放到点上进行差分,edge[i]表示节点i代表的边
int MAXLEN;//最长路径
struct SOLVE{
int u,v,lca,len;
}q[N];//这个结构体存的是T条链(ui,vi)的信息 inline int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar();
return f*x;
}
void write(int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
return;
} void add(int u,int v,int t)
{
tot++;
e[tot].to=v;
e[tot].next=he[u];
he[u]=tot;
e[tot].t=t;
return ;
}
void add_d(int u,int v)
{
tot++;
d[tot].to=v;
d[tot].next=hd[u];
hd[u]=tot;
return;
}
int fa[N];//并查集
int dis[N];//前缀和方便计算链长
int find(int x)
{
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
bool f[N];
void tarjan(int x,int pre)//tarjan求LCA
{
int y;
for(int i=he[x];i>0;i=e[i].next)
{
y=e[i].to;
if(y!=pre)
{
edge[y]=i;
dis[y]=dis[x]+e[i].t;
tarjan(y,x);
int fa_x=find(x);
int fa_y=find(y);
if(fa_x!=fa_y)
fa[fa_y]=fa_x;
f[y]=1;
}
}
for(int i=hd[x];i>0;i=d[i].next)
{
y=d[i].to;
if(f[y]){
int now=(i+1)>>1;//因为存的是双向边,所以第i条边对应的编号为(i+1)/2
q[now].lca=find(y);
q[now].len=dis[x]+dis[y]-2*dis[q[now].lca];
MAXLEN=max(MAXLEN,q[now].len);
}
}
}
int sum,max_len;//sum代表比当前check的x大的边的个数,即需要减小的边数
void dfs_spx(int x,int pre)//树上差分
{
int y;
for(int i=he[x];i>0;i=e[i].next)
{
y=e[i].to;
if(y!=pre)
{
dfs_spx(y,x);
spx[x]+=spx[y];
}
}
if(spx[x]==sum)//如果该边能够让所有链都覆盖
max_len=max(max_len,e[edge[x]].t);
}
bool check(int x)
{
for(int i=0;i<=n;i++) spx[i]=0;
sum=0;max_len=0;
for(int i=1;i<=m;i++)
{
if(q[i].len>x)
{
sum++;
spx[q[i].u]++;
spx[q[i].v]++;
spx[q[i].lca]-=2;
}
}
dfs_spx(1,0);
if(MAXLEN-max_len<=x)
return 1;
return 0;
} signed main()
{
n=read();m=read();
for(int i=1;i<n;++i)
{
int a,b,c;
a=read(),b=read(),c=read();
add(a,b,c);add(b,a,c);
}
tot=0;
for(int i=1;i<=n;++i) fa[i]=i;//并查集初始化
for(int i=1;i<=m;++i)
{
int u,v;
u=read(),v=read();
q[i].u=u;q[i].v=v;
add_d(u,v);add_d(v,u);
}
tarjan(1,0);
int st=0,ed=MAXLEN;
while(st<ed)
{
int mid=(st+ed)>>1;
if(check(mid)) ed=ans=mid;
else st=mid+1;
}
write(ans);
return 0;
}

[noip2015]运输计划(LCA,二分)的更多相关文章

  1. NOIP2015 运输计划(二分+LCA+差分)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 308  Solved: 208[Submit][Status] ...

  2. BZOJ 4326:NOIP2015 运输计划(二分+差分+lca)

    NOIP2015 运输计划Description公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所 ...

  3. LOJ2425 NOIP2015 运输计划 【二分+LCA+树上差分】*

    LOJ2425 NOIP2015 运输计划 LINK 题意:给你一颗树,可以将任意一条边的权值变成0,然后求m条路径的长度的最小值 思路: 先二分最后的距离ans,然后我们把路程大于ans的所有路径拿 ...

  4. bzoj4326: NOIP2015 运输计划(二分+LCA+树上差分)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4326 题目大意:有一颗含有n个顶点的树,每两个点之间有一个边权,现在有m个运输计划,每个 ...

  5. [luogu2680] 运输计划 (lca+二分+树上差分)

    传送门 Description Input Output 一个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间. Sample Input 6 3 1 2 3 1 6 4 3 1 7 4 3 ...

  6. NOIP2015运输计划(二分答案)

    题目描述 公元2044年,人类进入了宇宙纪元. L国有n个星球,还有n-1条双向航道,每条航道建立在两个星球之间,这n-1条航道连通了L国的所有星球. 小P掌管一家物流公司,该公司有很多个运输计划,每 ...

  7. bzoj 4326: NOIP2015 运输计划(二分+树链剖分)

    传送门 题解: 树链剖分快速求解任意两点间的路径的权值和: 然后,二分答案: 此题的难点是如何快速求解重合路径? 差分数组可以否??? 在此之前先介绍一下相关变量: int fa[maxn]; int ...

  8. luogu2680 [NOIp2015]运输计划 (tarjanLca+二分答案+树上差分)

    我们先不会就二分一下答案,设它是x,我们要判断它能不能满足 为了满足这个答案,我们就要让原本路径长度大于x的所有路径都经过某条边,而且这条边还要大于等于最长的路径-x 于是运用树上差分的思想,对于所有 ...

  9. 2018.09.26 bzoj4326: NOIP2015 运输计划(二分+树上差分)

    传送门 简单树上操作. 先转边权为点权. 显然所有的询问操作对应的路径会有一些交点,那么我们可以直接二分答案,对于所有大于二分值的询问用树上差分维护,最后dfs一遍每个点被覆盖了几次,当前情况合法当且 ...

  10. [NOIp2015]运输计划 (二分 $+$ 树上差分)

    #\(\mathcal{\color{red}{Description}}\) \(Link\) 在一棵带有边权的树上,可以选择使一条边权为零.然后对于所有\(M\)条链,使其链长最大值最小. #\( ...

随机推荐

  1. KB0002.对DoraCloud的桌面模板系统盘进行扩容

    KB0002.对DoraCloud的桌面模板系统盘进行扩容 DoraCloud的桌面是根据桌面模板创建的.桌面模板包含了系统盘.有时系统盘的空间不满足需求,就需要对系统盘大小进行调整. 我们以Hype ...

  2. Vue +Spring Boot 前后端分离 的 项目 笔记

    Vue +Spring Boot 前后端分离 的 项目 笔记 前端部分 Vue 脚手架的搭建 1.在创建目录的上一目录执行命令 命令为 vue init webpack 项目名 再创建项目的时候会自动 ...

  3. 【Java并发入门】01 并发编程Bug的源头

    一.根本原因 「CPU.内存.磁盘之间的速度差异」 为了能同时执行多个任务,CPU 发展出时间片轮转.多核等 CPU 要从内存中读数据太慢了,所以给自己设置了缓存 CPU 读磁盘更慢了,所以可以让该线 ...

  4. 吉特日化MES & WMS 与周边系统集成架构

    作者:情缘   出处:http://www.cnblogs.com/qingyuan/ 关于作者:从事仓库,生产软件方面的开发,在项目管理以及企业经营方面寻求发展之路 版权声明:本文版权归作者和博客园 ...

  5. JS 这一次彻底理解插入排序

    壹 ❀ 引 在前两篇排序文章中,我们分别介绍了冒泡排序与选择排序,趁热打铁,我们接着聊插入排序.老实说,在分析排序过程中头脑很清楚,过后再尝试写出排序代码还有点坎坷...可能是我脑瓜子不太机灵的问题, ...

  6. NC17247 H、Diff-prime Pairs

    题目链接 题目 题目描述 Eddy has solved lots of problem involving calculating the number of coprime pairs withi ...

  7. An Introduction to ANYDATA

    以下内容来自Oracle FAQ writen By Kevin,关于ANYDATA类型在项目中的应用. My newest project needed to create a record kee ...

  8. Vue+SpringBoot+ElementUI实战学生管理系统-1.项目介绍

    1.项目介绍 前段时间有位老铁问老徐有没有Vue+SpringBoot+ElementUI前后分离的项目想学习下,抱歉前端时间有点忙.千呼万唤始出来,做得不是很到位,需要的朋友可以拿去自己定制.:) ...

  9. RK3588开发笔记(二):基于方案商提供sdk搭建引入mpp和sdk的宿主机交叉编译Qt5.12.10环境

    前言   上一篇项目已经构建好了Qt,板子接入mipi屏幕也跑起来了,Qt也能正常运行了,现在需要接入定制开发的sdk,sdk中使用了硬解码等资源涉及到bsp的mpp,所以下一步就是引入mpp和sdk ...

  10. J-link虚拟串口波特率异常问题

    J-LINK V9以上自带了虚拟串口,使用非常方便. 但最近遇到问题,发现打开虚拟串口时电脑接收到的是乱码.到官网搜索了一下,发现最高波特率是115200,我使用的是256000,于是降低波特率. 官 ...