【Luogu】P2680运输计划(树上差分+二分)
总体思路……怎么说呢……是个暴力吧……
首先用倍增预处理出每条路径的长度。 然后按长度把路径排序。
然后二分答案。对于当前答案mid检验,怎么检验呢?
首先差分把所有长度比mid大的链上除了LCA之外的所有点权+1。dfs求出每个点的点权,顺便记下有多少点是被所有路径经过的。对于这些点,如果有一个点使得它到他的父亲那条边被删掉后,长度最长的路径都能卡过mid,那么返回true.
那么检查所有点发现长度最长的路径卡不过mid,那么返回false。
然后这题搞完了。
#include<cstdio>
#include<cstdlib>
#include<cctype>
#include<cstring>
#include<algorithm> using namespace std;
int n,m; inline int read(){
int num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct Edge{
int next,to,dis;
}edge[];
int head[],num;
inline void add(int from,int to,int dis){
edge[++num]=(Edge){head[from],to,dis};
head[from]=num;
}
struct Node{
int from,to,dis,lca;
bool operator <(const Node &a)const{
return dis>a.dis;
}
}q[];
int s[][],d[][];
int deep[];
int vis[],e[];
int pos[],tot;
int Max,ans; void find(int x,int fa){
deep[x]=deep[fa]+;
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(to==fa) continue;
s[to][]=x;d[to][]=edge[i].dis;find(to,x);
}
} void dfs(int x,int fa,int size){
e[x]=vis[x];
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(to==fa) continue;
dfs(to,x,size);
e[x]+=e[to];
}
if(e[x]==size) pos[++tot]=x;
} bool check(int limit){
memset(vis,,sizeof(vis));
int size=;tot=;
for(int i=;i<=m;++i){
if(q[i].dis<=limit) break;
vis[q[i].from]++;vis[q[i].to]++;vis[q[i].lca]-=;
size++;
}
dfs(,,size);
for(int i=;i<=tot;++i)
if(q[].dis-d[pos[i]][]<=limit) return ;
return ;
} int main(){
n=read(),m=read();
for(int i=;i<n;++i){
int from=read(),to=read(),dis=read();
add(from,to,dis);
add(to,from,dis);
}
for(int i=;i<=m;++i) q[i]=(Node){read(),read(),,};
find(,);
for(int j=;j<;++j)
for(int i=;i<=n;++i){
s[i][j]=s[s[i][j-]][j-];
d[i][j]=d[i][j-]+d[s[i][j-]][j-];
}
for(int i=;i<=m;++i){
int from=q[i].from,to=q[i].to; int &dis=q[i].dis,&lca=q[i].lca;
if(deep[from]<deep[to]) swap(from,to);
int f=deep[from]-deep[to];
for(int j=;(<<j)<=f;++j)
if(f&(<<j)){
dis+=d[from][j];
from=s[from][j];
}
if(from==to){
lca=from;
Max=max(Max,dis);
continue;
}
for(int j=;j>=;--j){
if(s[from][j]==s[to][j]) continue;
dis+=d[from][j]+d[to][j];
from=s[from][j];to=s[to][j];
}
dis+=d[from][]+d[to][];
lca=s[from][];
Max=max(Max,dis);
}
sort(q+,q+m+);
int l=,r=Max;
while(l<=r){
int mid=(l+r)>>;
if(check(mid)){ ans=mid;r=mid-; }
else l=mid+;
}
printf("%d",ans);
return ;
}
【Luogu】P2680运输计划(树上差分+二分)的更多相关文章
- [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告
[NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...
- 洛谷P2680 运输计划——树上差分
题目:https://www.luogu.org/problemnew/show/P2680 久违地1A了好高兴啊! 首先,要最大值最小,很容易想到二分: 判断当前的 mid 是否可行,需要看看有没有 ...
- NOIP2015 运输计划 (树上差分+二分答案)
---恢复内容开始--- 题目大意:给你一颗树,你可以把其中一条边的边权改成0,使给定的一些树链的权值和的最大值最小 把lenth定义为未修改边权时的答案 考虑二分答案,如果二分的答案成立,设修改成0 ...
- Luogu P2680 运输计划(二分+树上差分)
P2680 运输计划 题意 题目背景 公元\(2044\)年,人类进入了宇宙纪元. 题目描述 公元\(2044\)年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道 ...
- [luogu]P2680 运输计划[二分答案][树上差分]
[luogu]P2680 [NOIP2015]运输计划 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n ...
- luogu P2680 运输计划 (二分答案+树上差分)
题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间 ...
- luogu P2680 运输计划
传送门 要最长链的长度最短,一秒想到二分,因为如果对于某个长度满足改掉一边的边权后能使得所有链长度不超过该长度,则所有比他长的长度也满足. 二分最终答案.我们要使得原来长度大于二分的\(mid\)的链 ...
- luogu P2680 运输计划 65分做法
临近\(noip,AK\)不太现实,暴力才是王道,大佬无视 这里只介绍\(65\)分做法 ① \(m==1\) 的情况 很明显 就一条路径,当然要贪心选着一条路径路上的最大的边喽 傻逼分\(get 2 ...
- 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)
P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...
- P2680 运输计划(二分+树上差分)
P2680 运输计划 链接 分析: 二分+树上差分. 首先可以二分一个答案,那么所有比这个答案大的路径,都需要减去些东西才可以满足这个答案. 那么减去的这条边一定在所有的路径的交集上. 那么如果求快速 ...
随机推荐
- WebService学习之旅(二)JAX-WS基于Web容器发布WebService
在上节中我们定义Web服务接口和实现类后,调用Endpoint类的静态方法publish发布来webservice,这种方法使用起来虽然简单,但是对于一个企业级应用来说通常对外提供的服务可能不止一个, ...
- rpm包的安装方法
每次都记不住,这次必须整理一下!cd到你存放rpm文件包的目录rpm -ivh linuxqq-v1.0.2-beta1.i386.rpm安装时可能会遇到缺少包的错误.rpm -ivh --repla ...
- C# 语言 类
++++String类+++++黑色小扳手 - 属性紫色立方体 - 方法 ***字符串.Length - 字符串长度,返回int类型 字符串.TrimStart() - 去掉前空格字符串.TrimEn ...
- 洛谷 P1464 Function
题目描述 对于一个递归函数w(a,b,c) 如果a<=0 or b<=0 or c<=0就返回值1. 如果a>20 or b>20 or c>20就返回w(20,2 ...
- 51nod 1174 区间中最大的数(送盾题)
基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 给出一个有N个数的序列,编号0 - N - 1.进行Q次查询,查询编号i至j的所有数中,最大的数是多少. ...
- Codeforces A ACM (ACronym Maker) (dp)
http://codeforces.com/gym/100650 概要:给出一个缩写,和一些单词,从单词中按顺序选一些字母作为缩写,问方案数. 限制:某些单词要忽略,每个单词至少要选一个字母. dp[ ...
- Scalatra
SBT和giter8 在你开始着手之前,你需要安装两个工具(我假设你已经安装了JDK1.6+).我将给你提供简缩的安装指令,详细版的安装指令可通过 下面的scalatra页面找到( http://ww ...
- 修改linux的时区问题
修改linux的时区问题 配置服务器节点上的时区的步骤: 1.先生成时区配置文件Asia/Shanghai,用交互式命令 tzselect 即可: 2.拷贝该时区文件,覆盖系统本地时区配置: cp / ...
- Android Studio 中安装 apk 被拆分成多个 slice,如何禁止?
Android Studio 3.0.1 中,Run 'app' 时,生成的 apk 被分割成多个 slice: $ adb install-multiple -r D:\...\app\build\ ...
- glove 安装错误
https://stackoverflow.com/questions/44921611/error-installing-glove-python-link-exe-failed-with-exit ...