传送门啦

要求的就是,把树上的一条边的权值设为0之后,所有路径中的最大值的最小值。

首先二分最大值,假设某次二分的最大值为x,我们首先找出所有大于x的路径(也就是我们需要通过改权缩短的路径),并把路径上的所有边都标记一下。

在标记完成后,枚举所有边,如果存在一条边位于所有长度大于于x的路径上,并且删除之后能使所有路径都满足 $ length<=x $ ,则返回 $ true $ ,否则 $ false $ 。

还有一个问题就是,对于某个路径,如何快速标记出他经过的所有边呢?我们可以使用差分,用树上前缀和来表示某个点被标记次数。比如某条边 $ E(u,v) $ ,先把 $ sum[u]+=1,sum[v]+=1 $ ,然后 $ sum[lca(u,v)]-=2 $

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define re register
using namespace std;
const int maxn = 300005; inline int read(){
char ch = getchar();
int f = 1 , x = 0;
while(ch > '9' || ch < '0'){if(ch == '-') f = -1;ch = getchar();}
while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + ch - '0';ch = getchar();}
return x * f;
} int n,m,a,b,t,u[maxn],v[maxn];
int head[maxn],tot;
int f[maxn][21],ans; struct Edge{
int from,to,val,next;
}edge[maxn << 1]; inline void add(int u , int v , int w){
edge[++tot].from = u;
edge[tot].to = v;
edge[tot].val = w;
edge[tot].next = head[u];
head[u] = tot;
} int dep[maxn],dis[maxn],value[maxn],len[maxn];
int id[maxn],cnt; inline void dfs(int x , int fa) {
id[++cnt] = x;
dep[x] = dep[fa] + 1;
f[x][0] = fa;
for(re int i = 1 ; (1 << i ) <= dep[x] ; ++i)
f[x][i] = f[f[x][i - 1]][i - 1];
for(re int i = head[x] ; i ; i = edge[i].next) {
int v = edge[i].to;
if(v == fa) continue;
dis[v] = dis[x] + edge[i].val;
value[v] = edge[i].val;
dfs(v , x);
}
} inline int lca(int u , int v){
if(dep[u] < dep[v]) swap(u , v);
for(re int i = 18 ; i >= 0 ; --i)
if((1 << i) <= (dep[u] - dep[v]))
u = f[u][i];
if(u == v) return u;
for(re int i = 18 ; i >= 0 ; --i){
if((1 << i) <= dep[u] && f[u][i] != f[v][i]) {
u = f[u][i] ;
v = f[v][i] ;
}
}
return f[u][0];
} int sum[maxn]; inline bool check(int k){
for(re int i = 1 ; i <= n ; ++i)
sum[i] = 0;
int maxx = 0 , cnt = 0 ;
for(re int i = 1 ; i <= m ; ++i) {
if(len[i] > k) {
maxx = max(maxx , len[i]) ;
cnt++;
sum[u[i]]++; sum[v[i]]++;
sum[lca(u[i] , v[i])] -= 2;
}
}
for(re int i = n ; i >= 0 ; i--)
sum[f[id[i]][0]] += sum[id[i]] ;
for(re int i = 1 ; i <= n ; ++i)
if(sum[i] >= cnt && maxx - value[i] <= k)
return true;
return false;
} int main(){
n = read() ; m = read();
for(re int i = 1 ; i <= n - 1 ; ++i){
a = read(); b = read(); t = read();
add(a , b , t);
add(b , a , t);
}
dfs(1 , 0);
int l = 0 , r = 0 ;
for(re int i = 1 ; i <= m ; ++i){
u[i] = read(); v[i] = read();
len[i] = dis[u[i]] + dis[v[i]] - 2 * dis[lca(u[i] , v[i])] ;
r = max(r , len[i]);
}
while(l <= r) {
int mid = (l + r) >> 1;
if(check(mid)) {
ans = mid;
r = mid - 1 ;
}
else l = mid + 1;
}
printf("%d\n",ans);
return 0;
}

洛谷P2680运输计划的更多相关文章

  1. 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)

    P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...

  2. 洛谷 P2680 运输计划 解题报告

    P2680 运输计划 题目背景 公元2044年,人类进入了宇宙纪元. 题目描述 公元2044年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道,每条航道建立在两个星 ...

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

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

  4. 洛谷P2680 运输计划 [LCA,树上差分,二分答案]

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

  5. 洛谷 P2680 运输计划(NOIP2015提高组)(BZOJ4326)

    题目背景 公元 \(2044\) 年,人类进入了宇宙纪元. 题目描述 公元\(2044\) 年,人类进入了宇宙纪元. L 国有 \(n\) 个星球,还有 \(n-1\) 条双向航道,每条航道建立在两个 ...

  6. 洛谷 P2680 运输计划

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

  7. 洛谷——P2680 运输计划

    https://www.luogu.org/problem/show?pid=2680 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每 ...

  8. 洛谷P2680 运输计划——树上差分

    题目:https://www.luogu.org/problemnew/show/P2680 久违地1A了好高兴啊! 首先,要最大值最小,很容易想到二分: 判断当前的 mid 是否可行,需要看看有没有 ...

  9. 洛谷P2680 运输计划

    大概就是二分+树上差分... 题意:给你树上m条路径,你要把一条边权变为0,使最长的路径最短. 最大的最小,看出二分(事实上我并没有看出来...) 然后二分k,对于所有大于k的边,树上差分求出最长公共 ...

随机推荐

  1. bzoj2755【SCOI2012】喵星人的入侵

    输入格式 第一行为三个整数n,m,K,分别表示地图的长和宽,以及最多能放置的炮塔数量. 接下来的n行,每行包含m个字符,‘#’表示地图上原有的障碍,‘.’表示该处为空地,数据保证在原地图上存在S到T的 ...

  2. D. Dog Show 2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest, qualification stage (Online Mirror, ACM-ICPC Rules, Teams Preferred)

    http://codeforces.com/contest/847/problem/D 巧妙的贪心 仔细琢磨... 像凸包里的处理 #include <cstdio> #include & ...

  3. 闲:测试memcpy和std::copy vector之间拷贝

    预测:底层C函数肯定比stl算法快 结果:少量数据底层快,大数据以上则stl对vector的处理可能更好 C/C++: #include <iostream> #include <v ...

  4. 同一个局域网中用Windows自己的远程桌面远程局域网中的其他PC

    同一个局域网中用Windows自己的远程桌面远程局域网中的其他PC... ===================== 建立Windows远程访问的前提: 1.访问PC和被访问的PC在同一个局域网中 2 ...

  5. P4782 【模板】2-SAT 问题 && 2-SAT问题

    2-SAT到图论 \(k-SAT\) 是 k-适应性问题(Satisfiability)的简称. \(k-SAT\) 问题(除 \(k = 2\))已被证明为是 \(NP\) 完全问题, 而对于 \( ...

  6. RCNN,fast R-CNN,faster R-CNN

    转自:https://www.cnblogs.com/skyfsm/p/6806246.html object detection我的理解,就是在给定的图片中精确找到物体所在位置,并标注出物体的类别. ...

  7. Excel 中 VLOOKUP() 函数小结

    应用场景: 数据仓库上游源系统的数据库表变更,现在需要拆分一部分数据出来,单独放到一张新表中.假设原表为A,新表为B,B表和A表结构大部分一样,只有字段的前缀不同,那么我们如何找出到底有哪些字段不同呢 ...

  8. python---CMDB配置管理数据库

    前戏:项目目的 是一个运维自动化管理项目: 为了减少人工干预,降低人员成本 ---资产管理 --操作管理 避免人员直接操作服务器,使用后台去统一操作 一:实现方式 (一)Agent基于shell命令实 ...

  9. Vuex深入理解

    store下的index.js: import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) let store = new Vuex.St ...

  10. mongo查询日期格式数据

    /ali/mongodb/bin/mongo -u user -p '123456' 127.0.0.1:27017/KYElog ISODate方式 db.col_02.find({"Lo ...