luoguP2680 运输计划 题解(二分答案+树上差分)
P2680 运输计划 题目
这道题如果是看的我的树上差分来的,那么肯定一看题目就可以想到树上差分.
至于这是怎么想到的,一步一步来:
1.n有300000,不可能暴力枚举每一条边
2.因为我们要使运输时间的最大值最小,所以,考虑二分答案(做多了之后的习惯(其实也就是突然的灵感,不是必然......))
3.既然二分了答案,暂且把我们二分的答案变量名叫 lim ,考虑On的check():
想到每次把超过lim(跑LCA求运输计划的时间)的运输计划全部要考虑删边(显然),并且这些计划都必须要删一条公共边(也是显然,加虫洞就相当于把边权变为0,姑且叫做删边把),这就可以考虑差分了,把超过lim的计划全部差分进去,统计一下差分数组,枚举所有计划都经过的边(也就是差分数组==超过lim的计划数),看看最大的运输代价减去这个边权(相当于把它变为0,显然)是否小于lim, return1/0(显然最大值都小于lim了,所有的都小于lim了); 完成check()!
上代码:
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<ctime>
#include<queue>
#include<stack>
#define rg register
#define lst long long
#define N 300050
using namespace std; int n,m,cnt,ans,maxn,le,ri;
struct EDGE{
int to,v,nxt;
}edge[N<<];
struct ROAD{
int fm,to,v;
}road[N];
int head[N],back[N];
int cf[N];
int deep[N],fa[N];
int f[N][],g[N][]; inline int read()
{
rg int s=,m=;rg char ch=getchar();
while(ch!='-'&&(ch<''||ch>''))ch=getchar();
if(ch=='-')m=-,ch=getchar();
while(ch>=''&&ch<='')s=(s<<)+(s<<)+ch-'',ch=getchar();
return s*m;
} inline void add(rg int p,rg int q,rg int o)
{
edge[++cnt].to=q,edge[cnt].v=o;
edge[cnt].nxt=head[p];
head[p]=cnt;
} void dfs(rg int now,rg int fm,rg int dep,rg int s)//dfs预处理倍增LCA
{
fa[now]=fm,deep[now]=dep;
f[now][]=fm;g[now][]=s;
for(rg int i=;i<=;++i)
{
f[now][i]=f[f[now][i-]][i-];
g[now][i]=g[f[now][i-]][i-]+g[now][i-];
}
for(rg int i=head[now];i;i=edge[i].nxt)
{
rg int qw=edge[i].to;
if(qw!=fm)
{
back[qw]=i;
dfs(qw,now,dep+,edge[i].v);
}
}
} inline int LCA(rg int x,rg int y,rg int op)//倍增跳LCA
{
rg int res=;
if(deep[x]<deep[y])swap(x,y);
while(deep[x]>deep[y])//跳到同样深度
for(rg int i=;i>=;--i)
if(deep[f[x][i]]>=deep[y])res+=g[x][i],x=f[x][i]; while(x!=y)
{
for(rg int i=;i>=;--i)
if(f[x][i]!=f[y][i])
res+=g[x][i]+g[y][i],x=f[x][i],y=f[y][i]; if(fa[x]==fa[y])res+=g[x][]+g[y][],x=y=fa[x];
}
if(!op)return res;
else return x;
} inline void Insert(rg int p,rg int q)//差分
{
rg int lca=LCA(p,q,);
cf[p]++,cf[q]++,cf[lca]-=;
} void sum(rg int now)//统计差分数组
{
for(rg int i=head[now];i;i=edge[i].nxt)
{
rg int qw=edge[i].to;
if(qw!=fa[now])
{
sum(qw);
cf[now]+=cf[qw];
}
}
} inline int check(rg int lim)//如解析,check()
{
rg int ss=,Max=;
for(rg int i=;i<=n;++i)cf[i]=;
for(rg int i=;i<=m;++i)
{
if(road[i].v>lim)
{
Max=max(Max,road[i].v);
ss++,Insert(road[i].fm,road[i].to);
}
}
sum();
for(rg int i=;i<=n;++i)
if(cf[i]==ss&&Max-edge[back[i]].v<=lim)return ;
return ;
} int main()
{
n=read(),m=read();
for(rg int i=;i<n;++i)
{
rg int p=read(),q=read(),o=read();
add(p,q,o),add(q,p,o);
}
//读入边的信息
dfs(,,,);
for(rg int i=;i<=m;++i)
{
rg int p=read(),q=read();
road[i].fm=p,road[i].to=q,road[i].v=LCA(p,q,);
ri=max(ri,road[i].v);
}
add(,,);//没事干加了一个 0->1 的边,感觉比较踏实(0的父亲是1)...无语...
while(le<=ri)//二分
{
rg int mid=(ri+le)>>;
if(check(mid))ans=mid,ri=mid-;
else le=mid+;
}
printf("%d\n",ans);
return ;
}
luoguP2680 运输计划 题解(二分答案+树上差分)的更多相关文章
- luogu2680 [NOIp2015]运输计划 (tarjanLca+二分答案+树上差分)
我们先不会就二分一下答案,设它是x,我们要判断它能不能满足 为了满足这个答案,我们就要让原本路径长度大于x的所有路径都经过某条边,而且这条边还要大于等于最长的路径-x 于是运用树上差分的思想,对于所有 ...
- BZOJ 4326 NOIP2015 运输计划(二分答案 + 树上差分思想)
题目链接 BZOJ4326 这个程序在洛谷上TLE了……惨遭卡常 在NOIP赛场上估计只能拿到95分吧= = 把边权转化成点权 首先求出每一条路径的长度 考虑二分答案,$check(now)$ 对于 ...
- bzoj4326: NOIP2015 运输计划(二分+LCA+树上差分)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4326 题目大意:有一颗含有n个顶点的树,每两个点之间有一个边权,现在有m个运输计划,每个 ...
- LOJ2425 NOIP2015 运输计划 【二分+LCA+树上差分】*
LOJ2425 NOIP2015 运输计划 LINK 题意:给你一颗树,可以将任意一条边的权值变成0,然后求m条路径的长度的最小值 思路: 先二分最后的距离ans,然后我们把路程大于ans的所有路径拿 ...
- NOIP2015运输计划(二分答案)
题目描述 公元2044年,人类进入了宇宙纪元. L国有n个星球,还有n-1条双向航道,每条航道建立在两个星球之间,这n-1条航道连通了L国的所有星球. 小P掌管一家物流公司,该公司有很多个运输计划,每 ...
- [luogu]P2680 运输计划[二分答案][树上差分]
[luogu]P2680 [NOIP2015]运输计划 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n ...
- luogu P2680 运输计划 (二分答案+树上差分)
题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间 ...
- loj2425 「NOIP2015」运输计划[二分答案+树上差分]
看到题意最小化最长路径,显然二分答案,枚举链长度不超过$\text{mid}$,然后尝试检验.````` 检验是否存在这样一个边置为0后,全部链长$\le\text{mid}$,其最终目标就是.要让所 ...
- 【BZOJ-4326】运输计划 树链剖分 + 树上差分 + 二分
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 703 Solved: 461[Submit][Status] ...
随机推荐
- html-mailto
MailTo 属性 mailto 属性可以设置到a 标签和form 标签中 例如: <a href="mailto:****@qq.com">send mail< ...
- SQL 查询中not in 与 not exists 的区别
1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询,一直以来认为exists比in效率高的说法是不准确的.如果查询的两个表 ...
- vue 页面切换从右侧切入效果
1.将切换的页面用transition包裹 <div class="index-content"> <transition> <router-view ...
- 数据库_PXC群集与存储引擎
1. PXC介绍与群集搭建; 2.数据存储引擎. 一, PXC介绍 1.介绍 PXC(Percona XtraDB Cluster)基于Galara的一台开源软件,应用于解决mysql的高可用集群问题 ...
- HTML基础用 表格做报表
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 1、pip不是内部运行程序 解决方法
一.方式一 1.切换到pip所在路径: shit+ 右键. 再此处打开运行窗口 2.执行 pip install pytest 脚本即可. 二.方式二,添加环境变量 1.将pip所在的文件路径 添加到 ...
- torchvision.transforms模块介绍
torchvision.transforms模块 官网地址:https://pytorch.org/docs/stable/torchvision/transforms.html# torchvisi ...
- 刷题or源码链接
Hadoop权威指南的Github https://github.com/tomwhite/hadoop-book hadoopAPI http://hadoop.apache.org/docs/cu ...
- React笔记02——React中的组件
一个网页可以被拆分成若干小部分,每个部分都可以称为组件,即组件是网页中的一部分.组件中还可以有多个组件. 上一节中的App.js就是一个组件(继承了React.Component类的类). 一个组件的 ...
- spring+springMVC+mybatis框架整合——配置文件说明
如下图 web.xml配置说明: spring配置文件说明-1: spring配置文件说明-2: spring配置助记: 扫注(base) 读配(loc) 数据源(和comb(使用c3p0数据源)) ...