码农题啊兄弟们。

随便考虑二分一下,然后发现要取一条满足性质的边。

被所有大于\(mid\)的路径都覆盖,取了之后能把他们都弄到小于\(mid\)

那就树上差分再处理一下。

写了\(180h\),老年人复建训练。

NOIP2015 提高组] 运输计划
// Problem: P2680 [NOIP2015 提高组] 运输计划
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2680
// Memory Limit: 292.97 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org) #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
#define N 300005 inline ll read(){
char a = getchar();
ll ans = 0;
while(!((a <= '9') && (a >= '0')))
a = getchar();
while((a <= '9') && (a >= '0'))
ans = (ans << 3) + (ans << 1) + (a - '0'),a = getchar();
return ans;
} struct P{
ll to,v,next;
}e[N << 1]; ll cnt,head[N],s[N]; inline void add(int x,int y,int v){
e[++cnt].to = y;
e[cnt].v = v;
e[cnt].next = head[x];
head[x] = cnt;
} ll n,m; struct T{
ll l,r,sl;
}ta[N]; bool operator < (T a,T b){
return a.sl < b.sl;
} ll dep[N],f[N][32]; inline void dfs(int u,int fa){
f[u][0] = fa;
dep[u] = dep[fa] + 1;
for(int i = 1;i <= 30;++i)
f[u][i] = f[f[u][i - 1]][i - 1];
for(int i = head[u];i;i = e[i].next){
int v = e[i].to;
if(v == fa)continue;
s[v] = s[u] + e[i].v;
dfs(v,u);
}
} inline ll lca(ll x,ll y){
if(dep[x] < dep[y])
std::swap(x,y);
for(int i = 30;i >= 0;--i){
if(dep[f[x][i]] >= dep[y])
x = f[x][i];
if(x == y)
return x;
}
for(int i = 20;i >= 0;--i){
if(f[x][i] != f[y][i]){
x = f[x][i];
y = f[y][i];
}
}
return f[x][0];
} ll tag[N],va[N]; ll need;
bool p;
ll x; inline void del(int u,int fa){
for(int i = head[u];i;i = e[i].next){
int v = e[i].to;
if(v != fa){
del(v,u);
va[u] += va[v];
}
}
va[u] += tag[u];
// std::cout<<u<<" "<<tag[u]<<" "<<va[u]<<std::endl;
} inline void dfs2(int u,int fa,int v){
// std::cout<<u<<" "<<va[u]<<" "<<tag[u]<<" "<<fa<<" "<<v<<std::endl;
if(va[u] == need && ta[m].sl - v <= x){
p = 1;
return ;
}
for(int i = head[u];i;i = e[i].next){
int vi = e[i].to;
if(vi == fa)
continue;
dfs2(vi,u,e[i].v);
}
} inline bool check(){
// std::cout<<x<<":"<<std::endl;
std::memset(tag,0,sizeof(tag));
std::memset(va,0,sizeof(va));
need = 0;
for(int i = m;i >= 1;--i){
if(ta[i].sl > x){
int Lca = lca(ta[i].l,ta[i].r);
need ++ ;
if(Lca == ta[i].l){
tag[ta[i].l] -- ;
tag[ta[i].r] ++ ;
}else if(Lca == ta[i].r){
tag[ta[i].r] -- ;
tag[ta[i].l] ++;
}else {
// std::cout<<Lca<<" "<<ta[i].l<<" "<<ta[i].r<<std::endl;
tag[Lca] -= 2;
tag[ta[i].l] ++ ;
tag[ta[i].r] ++ ;
}
}
}
del(1,0);
p = 0;
dfs2(1,0,0);
return p;
} inline void find_ans(){a
std::sort(ta + 1,ta + m + 1);
ll l = 0,r = ta[m].sl;
#define mid ((l + r) >> 1)
while(l + 1 < r){
x = mid;
// std::cout<<l<<" "<<r<<" ";
if(check())
r = mid;
else
l = mid;
// std::cout<<l<<" "<<r<<std::endl;
}ac
r ++ ;
while(x = r - 1,check())
r--;
std::cout<<r<<std::endl;
} int main(){
n = read(),m = read();
for(int i = 1;i <= n - 1;++i){
ll l,r,v;
l = read(),r = read(),v = read();
add(l,r,v);
add(r,l,v);
}
for(int i = 1;i <= m;++i)
ta[i].l = read(),ta[i].r = read();
dfs(1,0);
for(int i = 1;i <= m;++i){
ll Lca = lca(ta[i].l,ta[i].r);
ta[i].sl = s[ta[i].l] + s[ta[i].r] - 2 * s[Lca];
}
// for(int i = 1;i <= m;++i)
// std::cout<<ta[i].sl<<std::endl;
find_ans();
}

NOIP2015 提高组] 运输计划的更多相关文章

  1. [NOIP2015 提高组] 运输计划题解

    题目链接:P2680 [NOIP2015 提高组] 运输计划 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 看了好长时间题解才终于懂的,有关lca和二分答案的题解解释的不详细,一时 ...

  2. [NOIP2015提高组]运输计划

    题目:BZOJ4326.洛谷P2680.Vijos P1983.UOJ#150.codevs4632.codevs5440. 题目大意:有一棵带权树,有一些运输计划,第i个运输计划从ai到bi,耗时为 ...

  3. 洛谷 P2680 [NOIP2015 提高组] 运输计划

    链接:P2680 题意: 在树上把一条边边权变为0使得最长给定路径最短 分析: 最大值最小可以想到二分答案,对于每一个mid,寻找所有大于mid的路径,再寻找是否存在一条边使得删去它后大于mid的路径 ...

  4. P2680 [NOIP2015 提高组] 运输计划 (树上差分-边差分)

    P2680 题目的大意就是走完m条路径所需要的最短时间(边权是时间), 其中我们可以把一条边的权值变成0(也就是题目所说的虫洞). 可以考虑二分答案x,找到一条边,使得所有大于x的路径都经过这条边(差 ...

  5. 【数据结构】运输计划 NOIP2015提高组D2T3

    [数据结构]运输计划 NOIP2015提高组D2T3 >>>>题目 [题目描述] 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航 ...

  6. 【题解】NOIP2015提高组 复赛

    [题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...

  7. 洛谷 P2678 & [NOIP2015提高组] 跳石头

    题目链接 https://www.luogu.org/problemnew/show/P2678 题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布 ...

  8. 【二分查找】 跳石头NOIP2015提高组 D2T1

    [二分查找]跳石头NOIP2015提高组 D2T1 >>>>题目 [题目描述] 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石 ...

  9. [NOIP2015] 提高组 洛谷P2615 神奇的幻方

    题目描述 幻方是一种很神奇的N*N矩阵:它由数字1,2,3,……,N*N构成,且每行.每列及两条对角线上的数字之和都相同. 当N为奇数时,我们可以通过以下方法构建一个幻方: 首先将1写在第一行的中间. ...

随机推荐

  1. 微服务网关Ocelot加入IdentityServer4鉴权-.NetCore(.NET5)中使用

    Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Consul服务注册,服务发现 Consul+Ocelot+Polly在.NetCore中使用(.NET5)-网关Ocel ...

  2. Android系统编程入门系列之应用权限的定义与申请

    在之前关于应用内数据本地保存为文件时,曾提到应用需要申请外部存储设备的读写权限才能访问外部存储中的文件.那么针对某一种权限,应用程序具体应该怎么申请使用呢?本文将详细介绍. 应用中的权限主要分为两类, ...

  3. 【UE4】GAMES101 图形学作业2:光栅化和深度缓存

    总览 在上次作业中,虽然我们在屏幕上画出一个线框三角形,但这看起来并不是那么的有趣.所以这一次我们继续推进一步--在屏幕上画出一个实心三角形,换言之,栅格化一个三角形.上一次作业中,在视口变化之后,我 ...

  4. 你知道什么是JUC了吗?

    多线程一直Java开发中的难点,也是面试中的常客,趁着还有时间,打算巩固一下JUC方面知识,我想机会随处可见,但始终都是留给有准备的人的,希望我们都能加油!!! 沉下去,再浮上来,我想我们会变的不一样 ...

  5. Redis:学习笔记-04

    Redis:学习笔记-04 该部分内容,参考了 bilibili 上讲解 Redis 中,观看数最多的课程 Redis最新超详细版教程通俗易懂,来自 UP主 遇见狂神说 10. Redis主从复制 1 ...

  6. 学习手册 | MySQL篇 · 其一

    InnoDB关键特性 插入缓冲(Insert Buffer) 问题:   在InnoDB插入的时候,由于记录通常都是按照插入顺序,也就是主键的顺序进行插入的,因此,插入聚集索引是顺序的,不需要随机IO ...

  7. 记录编译QGIS(3.4+Qt5.11+VS2015)的整个过程

    编译运行整个QGIS耗时耗力,由于本人比较愚钝,来来回回花了大概两个星期最终编译成功,记录一下整个过程,一方面备忘,另一方面可能也给别人一点借鉴. 1.准备工作 参考了许多网上的教程,李民录大神的&l ...

  8. Linux Shell Here Document

    Here Document 是一种有特殊用处的代码块,他使用IO重定向的形式记录了一段临时的文本或交互命令,并且把这些文本或命令 依次的传递给一个程序或一个命令,作为他运行时的标准输入. Here d ...

  9. poj 1330 Nearest Common Ancestors (最简单的LCA)

    题意: 给出一棵树的结构. 给出两个点X和Y,求它俩的LCA. 思路: 只需求两个点的LCA,用了两种方法,一种离线tarjan,一种直接搞. 看代码. 代码: 方法一:直接搞. int const ...

  10. request/response解决中文乱码!!!

    Request中文乱码问题以及解决方案 补充三个知识点: Get是URL解码方式.默认解码格式是Tomcat编码格式.所以URL解码是UTF-8,覆盖掉了request容器解码格式 Post是实体内容 ...