传送门啦

要求的就是,把树上的一条边的权值设为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. Git-balabala

    想必大家都听说过且用过Github(没听说过-.-),我也一直用Github管理我的代码到现在,如果你只是将其作为自己私有的代码仓库,那么平时用得最多的就是git clone, git add以及gi ...

  2. C++命名规则 (转载仅作参考)

    如果想要有效的管理一个稍微复杂一点的体系,针对其中事物的一套统一.带层次结构.清晰明了的命名准则就是必不可少而且非常好用的工具. 活跃在生物学.化学.军队.监狱.黑社会.恐怖组织等各个领域内的大量有识 ...

  3. UIImage加载图片的方式以及Images.xcassets对于加载方法的影响

    UIImage加载图片的方式以及Images.xcassets对于加载方法的影响 图片缓存 根据是否将创建好的对象缓存入系统内存,有两类创建UIImage对象的方法可选: 缓存:+ imageName ...

  4. ZABBIX 3.0 监控MongoDB性能【OK】

    系统环境: centos7.2 zabbix-3.4   一.原理  通过以下命令查看mongodb的状态: echo "db.serverStatus()" | mongo ad ...

  5. 题解 P1967 【货车运输】

    树链剖分+线段树 思路 貌似题解里没有树链剖分和线段树的,贡献一发. 首先明确题目要求:一辆车走某条路从x城到y城的边权最小值 我们把要求分开来看: 从x城到y城:我们需要走的路径将两点联通 边权最小 ...

  6. [Java] 集合框架原理之一:基本结构与源码分析

    一.Collection Collection 接口定义了一些基本的方法: int size(); boolean isEmpty(); boolean add(E e); boolean addAl ...

  7. windows下静态编译pthread

    1. Building the library as a statically linkable library-------------------------------------------- ...

  8. CSS3 渐变,rgba与hsla

    radial-gradient:径向渐变 ellipse:椭圆形渐变默认,circle:圆形渐变 定义渐变大小,指定终点位置: farthest-corner:默认,指定径向渐变的半径长度为:从圆心到 ...

  9. angularJS $http $q $promise

    一天早晨,爹对儿子说:“宝儿,出去看看天气如何!” 每个星期天的早晨,爹都叫小宝拿着超级望远镜去家附近最高的山头上看看天气走势如何,小宝说没问题,我们可以认为小宝在离开家的时候给了他爹一个promis ...

  10. 20155330 2016-2017-2 《Java程序设计》第五周学习总结

    20155330 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 学习目标 理解异常架构 掌握try...catch...finally处理异常的方法 会用t ...