题目地址

题目链接

题解

二分答案,那么大于答案的路径都需要有一条公共边,maxlen-val>=二分出来的x。val是边权。

考虑树剖,对每条大于答案的路径都+1(线段树里),枚举边,如果(线段树中的)值==大于答案的边数,那么对他们取max。

复杂度\(O((nlognlogn+m)logn)\)(可能不是特别准确因为没写树剖,不过是三个log的没错)

卡常?不,想想树剖的这两个log我们拿来干啥,给路径的链+1。有没有什么复杂度更低的方法?

考虑树上差分。

对每条大于答案的路径差分标记,dfs一遍统计答案,对被标记的次数等于 大于答案的路径条数 的边的边权取max,并对所有路径取max。

check判断max路径-max边是否大于二分出的x即可

复杂度\(O((n+m)logn)\)

#include <bits/stdc++.h>
using namespace std; #define in(x) (x = read())
inline int read() {
int x = 0, f = 1; char c = getchar();
while(c < '0' || c > '9') (c == '-') && (f = -1), c = getchar();
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
} #define N 300010
#define ll long long
int n = read(), m = read();
int head[N], cnt;
int d[N], val[N];
int dep[N], top[N], fa[N], siz[N];
struct edge {
int to, nxt, v;
}e[N<<1];
struct Node {
int x, y, lca;
int len;
}q[N]; void ins(int u, int v, int w) {
e[++cnt] = (edge) {v, head[u], w};
head[u] = cnt;
} void dfs1(int u) {
siz[u] = 1;
for(int i = head[u]; i; i = e[i].nxt) {
if(e[i].to == fa[u]) continue;
fa[e[i].to] = u;
dep[e[i].to] = dep[u] + 1;
val[e[i].to] = e[i].v;
d[e[i].to] = d[u] + e[i].v;
dfs1(e[i].to);
siz[u] += siz[e[i].to];
}
} void dfs2(int u, int topf) {
top[u] = topf;
int k = 0;
for(int i = head[u]; i; i = e[i].nxt) {
if(e[i].to == fa[u]) continue;
if(siz[e[i].to] > siz[k]) k = e[i].to;
}
if(!k) return;
dfs2(k, topf);
for(int i = head[u]; i; i = e[i].nxt) {
if(e[i].to == fa[u] || e[i].to == k) continue;
dfs2(e[i].to, e[i].to);
}
} int lca(int x, int y) {
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x, y);
return x;
} int res = 0, tot = 0, mx = 0;
void dfs(int u) {
for(int i = head[u]; i; i = e[i].nxt) {
if(e[i].to == fa[u]) continue;
dfs(e[i].to);
d[u] += d[e[i].to];
}
if(d[u] == tot) res = max(res, val[u]);
} bool check(ll x) {
memset(d, 0, sizeof(d));
res = 0; tot = 0; mx = 0;
for(int i = 1; i <= m; ++i) {
if(q[i].len <= x) continue;
d[q[i].x]++; d[q[i].y]++; d[q[i].lca] -= 2;
++tot;
mx = max(q[i].len, mx);
}
dfs(1);
if(mx - res > x) return 0;
return 1;
} int main(){
for(int i = 1, u, v, w; i < n; ++i) {
in(u), in(v), in(w);
ins(u, v, w), ins(v, u, w);
}
dfs1(1); dfs2(1, 1);
int Mx = 0;
for(int i = 1; i <= m; ++i) {
in(q[i].x); in(q[i].y);
q[i].lca = lca(q[i].x, q[i].y);
q[i].len = d[q[i].x] - d[q[i].lca] + d[q[i].y] - d[q[i].lca];
Mx = max(Mx, q[i].len);
}
int l = 1, r = Mx, ans = Mx;
while(l <= r) {
int mid = (l + r) >> 1;
if(check(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
printf("%d\n", ans);
}

LuoguP2680 运输计划的更多相关文章

  1. luoguP2680 运输计划 题解(二分答案+树上差分)

    P2680 运输计划  题目 这道题如果是看的我的树上差分来的,那么肯定一看题目就可以想到树上差分. 至于这是怎么想到的,一步一步来: 1.n有300000,不可能暴力枚举每一条边 2.因为我们要使运 ...

  2. [luoguP2680] 运输计划(lca + 二分 + 差分)

    传送门 暴力做法 50 ~ 60 枚举删边,求最大路径长度的最小值. 其中最大路径长度运用到了lca 我们发现,求lca的过程已经不能优化了,那么看看枚举删边的过程能不能优化. 先把边按照权值排序,然 ...

  3. bzoj 4326: NOIP2015 运输计划

    4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MB Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个 ...

  4. noip2015 运输计划

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

  5. 【bzoj4326】[NOIP2015]运输计划

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

  6. [题解]vijos 运输计划

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

  7. NOIP2015 运输计划(bzoj4326)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 886  Solved: 574[Submit][Status] ...

  8. UOJ #150 【NOIP2015】 运输计划

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

  9. [bzoj4326][NOIP2015]运输计划

    Description 公元2044年,人类进入了宇宙纪元. 国有个星球,还有条双向航道,每条航道建立在两个星球之间,这条航道连通了国的所有星球. 小掌管一家物流公司,该公司有很多个运输计划,每个运输 ...

随机推荐

  1. Vue系列之 => 模拟购物车添加小球动画

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 排序(Sort)-----插入排序

       声明:文中动画转载自https://blog.csdn.net/qq_34374664/article/details/79545940    1.插入排序简介 插入排序(InsertSort) ...

  3. jQuery选择器--selector1,selector2,selectorN和ancestor descendant

        selector1,selector2,selectorN 概述 将每一个选择器匹配到的元素合并后一起返回.你可以指定任意多个选择器,并将匹配到的元素合并到一个结果内 参数 selector1 ...

  4. RSA解密解密

    #!/usr/bin/env python # -*- coding:utf-8 -*- import rsa import base64 # ######### 1. 生成公钥私钥 ######## ...

  5. oracle查询每隔5分钟区间内的数据量

    SELECT COUNT (DISTINCT tmp.PLATE) totalNum, tmp.newTime FROM ( SELECT T .LICENSE_PLATE plate, TO_CHA ...

  6. 20155228 2016-2017-2 《Java程序设计》第3周学习总结

    20155228 2016-2017-2 <Java程序设计>第3周学习总结 教材学习内容总结 认识对象 类与对象 类和对象的关系:类是对象的设计图,对象是类的实例 参考:将"名 ...

  7. mongoDB3.4的sharding集群搭建及JavaAPI的简易使用

    第一部分 在搭建mongoDB之前,我们要考虑几个小问题: 1.我们搭建集群的目的是什么?是多备份提高容错和系统可用性还是横向拓展存储大规模数据还是两者兼有? 如果是为了多备份那么选择replicat ...

  8. 关于数据库主从表、主键PRIMARY KEY 外键约束 FOREIGN KEY 约束----NOT NULL,DEFAULT,CHECK

    如果由两个列共同组成主键,而且一个子表将主键作为可为空值的外键来继承,就可能得到错误的数据.可在一个外键列中插入有效的值,但在另一个外键列中插入空值.然后,可添加一个数据表检查约束,在可为空的外键中检 ...

  9. dalaozouleyeyaojianqiangdehuoxiaqu

    dalaozouleyeyaojianqiangdehuoxiaqu 没错,YY又开始哔哔了,非常不淡定,发个博客冷静一下反正没人看 好吧他们还是退役了,关键是我昨天竟然没看到博文???? (我是不会 ...

  10. The Little Prince-summary

    The Little Prince-summary 这些年 ”寂寞”这个词使用频率越来越高 这些年 不管有钱没钱 有对象没对象的人 入夜时分总是心里空空 不知生活的意义是什么 我们不喜欢一座城市 对一 ...