大概就是二分+树上差分...

题意:给你树上m条路径,你要把一条边权变为0,使最长的路径最短。

最大的最小,看出二分(事实上我并没有看出来...)

然后二分k,对于所有大于k的边,树上差分求出最长公共边,然后看是否可以。

(yy的解法②:边按照长度排序,然后二分。删除最长公共边。据logeadd juru说是三分)

代码量3.6k,180行,还是有点长的。

 #include <cstdio>
#include <algorithm>
#include <cstring>
const int N = ; inline void read(int &x) {
char c = getchar();
x = ;
while(c > '' || c < '') {
c = getchar();
}
while(c <= '' && c >= '') {
x = (x << ) + (x << ) + c - ;
c = getchar();
}
return;
} struct Edge {
int v, nex, len;
}edge[N << ]; int top; int e[N], n, m, lm, fa[N][], d[N], lenth[N]; /// 点
int l[N], r[N], mid[N], len[N]; /// 路径
bool use[N]; /// 树上差分
int num, large, R, f[N]; inline void add(int x, int y, int z) {
edge[++top].v = y;
edge[top].len = z;
edge[top].nex = e[x];
e[x] = top;
return;
} inline void DFS1(int x, int f) {
fa[x][] = f;
for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
if(y != f) {
lenth[y] = lenth[x] + edge[i].len;
d[y] = d[x] + ;
DFS1(y, x);
}
}
return;
} inline void getlca() {
while(( << lm) < n) {
lm++;
}
DFS1(, );
for(int i = ; i <= lm; i++) {
for(int x = ; x <= n; x++) {
fa[x][i] = fa[fa[x][i - ]][i - ];
}
}
return;
} inline int lca(int x, int y) {
if(d[x] > d[y]) {
std::swap(x, y);
}
int t = lm;
while(t > - && d[y] > d[x]) {
if(d[fa[y][t]] >= d[x]) {
y = fa[y][t];
}
t--;
}
if(x == y) {
return x;
}
t = lm;
while(t > - && fa[x][] != fa[y][]) {
if(fa[x][t] != fa[y][t]) {
x = fa[x][t];
y = fa[y][t];
}
t--;
}
return fa[x][];
} inline int DFS(int x) {
int cnt = ;
for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
if(y == fa[x][]) {
continue;
}
int temp = DFS(y);
cnt += temp;
if(temp == num) {
large = std::max(large, edge[i].len);
}
}
cnt += f[x];
return cnt;
} inline bool check(int k) {
num = ;
memset(f, , sizeof(f));
for(int i = ; i <= m; i++) {
bool t = len[i] > k;
use[i] = t;
num += t;
if(t) {
f[l[i]]++;
f[r[i]]++;
f[mid[i]] -= ;
}
}
large = ;
DFS();
return R - large <= k;
} inline int getlong(int i) {
int x = l[i];
int ans = ;
while(x != mid[i]) {
ans = std::max(ans, lenth[x] - lenth[fa[x][]]);
x = fa[x][];
}
x = r[i];
while(x != mid[i]) {
ans = std::max(ans, lenth[x] - lenth[fa[x][]]);
x = fa[x][];
}
return ans;
} int main() {
scanf("%d%d", &n, &m);
int x, y, z;
for(int i = ; i < n; i++) {
//scanf("%d%d%d", &x, &y, &z);
read(x);
read(y);
read(z);
add(x, y, z);
add(y, x, z);
}
getlca();
int dr = , dl = , dm, A = ;
for(int i = ; i <= m; i++) {
//scanf("%d%d", &l[i], &r[i]);
read(l[i]);
read(r[i]);
mid[i] = lca(l[i], r[i]);
len[i] = lenth[l[i]] + lenth[r[i]] - * lenth[mid[i]];
if(len[i] > dr) {
dr = len[i];
A = i;
}
}
R = dr;
dl = dr - getlong(A);
if(dl < ) {
printf("ERROR ");
}
while(dl < dr) {
dm = (dr + dl) / ;
if(check(dm)) {
//printf("check %d 1 \n", dm);
dr = dm;
}
else {
//printf("check %d 0 \n", dm);
dl = dm + ;
}
}
printf("%d", dr);
return ;
}

AC代码

洛谷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运输计划

    传送门啦 要求的就是,把树上的一条边的权值设为0之后,所有路径中的最大值的最小值. 首先二分最大值,假设某次二分的最大值为x,我们首先找出所有大于x的路径(也就是我们需要通过改权缩短的路径),并把路径 ...

随机推荐

  1. C#使用FFMPEG推流,并且获取流保存在本地,随时取媒体进行播放!

    最近开发了基于C#的推流器一直不大理想,终于在不懈努力之后研究了一点成果,这边做个笔记:本文着重在于讲解下如何使用ffmpeg进行简单的推流,看似简单几行代码没有官方的文档很吃力.并获取流的源代码:如 ...

  2. [UWP 自定义控件]了解模板化控件(4):TemplatePart

    1. TemplatePart TemplatePart(部件)是指ControlTemplate中的命名元素.控件逻辑预期这些部分存在于ControlTemplate中,并且使用protected ...

  3. Jmeter(三十四)_Beanshell解析并提取json响应

    1:前置条件 将fastjson-1.2.49.jar包置于jmeter的lib目录下,并将该jar包添加到测试计划的Library中:否则会报:Typed variable declaration ...

  4. C#_根据银行卡卡号判断银行名称

    /// <summary> /// 银行信息 /// </summary> public class BankInfo { #region 数组形式存储银行BIN号 /// & ...

  5. .net 2.0 使用linq

    .net 2.0 使用linq,主要是使用Linq to Object,没有测试Linq to XML. 方法: 新建一个net2.0的程序,然后添加对System.Core.Dll的引用.引用时vs ...

  6. linux-阿里云仓库搭建-搭建本地仓库-yum

    以上是同步元数据信息 安装完成———————————————————————————— 本地库的搭建 是建立在rpm之上的封装 可用的包 把仓库信息链接到本地 使用中文显示, 我们平时用的是oracl ...

  7. Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)-C. Plasticine zebra

    问了学长,感觉还是很迷啊,不过懂了个大概,这个翻转操作,实质不就是在序列后面加上前面部分比如 bw | wwbwwbw  操作过后 wbwbwwbww 而 bw | wwbwwbwbw 这样我们就知道 ...

  8. MYSQL ROW_FORMAT=Compact

    https://dev.mysql.com/doc/refman/5.6/en/innodb-row-format-antelope.html https://docs.oracle.com/cd/E ...

  9. Install alipay支付宝安全控件 on firefox in linux

    [root@rgqancy 下载]# ./aliedit.sh建议以非root账号安装支付宝安全控件请重启   firefox   使插件生效成功安装 支付宝安全控件请按任意键退出... what i ...

  10. asp.net core 2.0中的配置(1)---Configuration

    配置就是一个装配数据字典的过程,一个字典也就是一个键值对,所以从配置就是键值对. 在asp.net core中关于配置是由四个基本的类型来支撑的,是①IConfigurationSource②ICon ...