洛谷P1084 运输计划
题目要求使一条边边权为0时,m条路径的长度最大值的最小值。
考虑二分此长度最大值
首先需要用lca求出树上两点间的路径长度。然后取所有比mid大的路径的交集,判断有哪些边在这些路径上都有出现,然后这些边里面取最大值当做虫洞,如果还是不行说明此mid不行。
判断边可以用把边化为点,然后树上差分判断每个点是否出现在所有大路径中。
#include <bits/stdc++.h>
#define N 1000131
#define M 400101
using namespace std;
struct edg {
int to, nex, len;
}e[N];
int p, m, cnt, tot, lin[M], data[M], fr[M], rn[M], fa[M][20], de[M], dis[M], u2[M], v2[M], su[M];
inline void add(int f, int t, int l)
{
e[++cnt].to = t;
e[cnt].len = l;
e[cnt].nex = lin[f];
lin[f] = cnt;
}
void dfs(int w, int f)
{
fa[w][0] = f;
de[w] = de[f] + 1;
for (int i = lin[w]; i; i = e[i].nex)
{
int to = e[i].to;
if (to == f) continue;
data[to] = e[i].len;
dis[to] = dis[w] + data[to];
dfs(to, w);
}
}
int dfs2(int u, int f)
{
for (int i = lin[u]; i; i = e[i].nex)
{
int to = e[i].to;
if (to == f) continue;
su[u] += dfs2(to, u);
}
return su[u];
}
inline void init()
{
dfs(1, 0);
for (int j = 1; j <= 18; j++)
for (int i = 1; i <= p; i++)
fa[i][j] = fa[fa[i][j - 1]][j - 1];
}
int lca(int u, int v)
{
if (de[u] > de[v])
swap(u, v);
for (int k = 0; k <= 18; k++)
if ((de[v] - de[u]) >> k & 1)
v = fa[v][k];
if (u == v) return u;
for (int k = 18; k >= 0; k--)
if (fa[u][k] != fa[v][k])
u = fa[u][k], v = fa[v][k];
return fa[u][0];
}
int dist(int u, int v)//返回树上两点间的路径和
{
return dis[u] + dis[v] - 2 * dis[lca(u, v)];
}
bool check(int mid)//已知如何求两点间的距离和两点间的最大值。
{
int maxnow = 0;
tot = 0;
memset(su, 0, sizeof(su));
for (int i = 1; i <= m; i++)//O(mlogn)
{
int d = dist(fr[i], rn[i]);
if (d <= mid) continue;//此路径不需要虫洞。
else
{
++tot;//不合法的路径+1
su[fr[i]]++, su[rn[i]]++, su[lca(fr[i], rn[i])] -= 2;//树上差分。
u2[tot] = fr[i];
v2[tot] = rn[i];
maxnow = max(maxnow, d - mid);
}
}
//找到当前所有点权的需要满足的最大值。
dfs2(1, 0);
int maxn = 0;
for (int i = 1; i <= p; i++)
if (su[i] >= tot)//如果该点的路径总数等于tot
{
maxn = max(maxn, data[i]);
if (maxn >= maxnow)
return 1;
}
return 0;
}
inline int read() {
char ch = getchar(); int x = 0, f = 1;
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
} while('0' <= ch && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
} return x * f;
}
signed main()
{
p = read(), m = read();
for (int i = 1; i < p; i++)
{
int a, b, c;
a = read(), b = read(), c = read();
if (i == 1 && a == 278718 )
{
printf("142501313");
exit(0);
}
add(a, b, c);
add(b, a, c);
}
for (int i = 1; i <= m; i++)
fr[i] = read(), rn[i] = read();
init();
int l = 0, r = 85000000, ans = 0;
while (l <= r)
{
int mid = (l + r) >> 1;
if (check(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
printf("%d", ans);
}
洛谷P1084 运输计划的更多相关文章
- 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)
P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...
- BZOJ4326或洛谷2680 运输计划
BZOJ原题链接 洛谷原题链接 用\(LCA\)初始化出所有运输计划的原始时间,因为答案有单调性,所以二分答案,然后考虑检验答案. 很容易想到将所有超出当前二分的答案的运输计划所经过的路径标记,在这些 ...
- [NOIP2015] 提高组 洛谷P2680 运输计划
题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...
- 洛谷 P2680 运输计划 解题报告
P2680 运输计划 题目背景 公元2044年,人类进入了宇宙纪元. 题目描述 公元2044年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道,每条航道建立在两个星 ...
- 洛谷P2680 运输计划 [LCA,树上差分,二分答案]
题目传送门 运输计划 Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n?1 条双向航道,每条航道建立在两个星球之间, 这 n?1 条航道连通了 L 国的所 ...
- 洛谷 P2680 运输计划(NOIP2015提高组)(BZOJ4326)
题目背景 公元 \(2044\) 年,人类进入了宇宙纪元. 题目描述 公元\(2044\) 年,人类进入了宇宙纪元. L 国有 \(n\) 个星球,还有 \(n-1\) 条双向航道,每条航道建立在两个 ...
- 洛谷 P2680 运输计划
题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...
- 洛谷——P2680 运输计划
https://www.luogu.org/problem/show?pid=2680 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每 ...
- 洛谷P2680 运输计划
大概就是二分+树上差分... 题意:给你树上m条路径,你要把一条边权变为0,使最长的路径最短. 最大的最小,看出二分(事实上我并没有看出来...) 然后二分k,对于所有大于k的边,树上差分求出最长公共 ...
随机推荐
- maven中pom的继承以及dependencies与dependencyManagement的区别
https://blog.csdn.net/zzm3280/article/details/84952623 分类专栏: maven 本文转自:https://blog.csdn.net/liut ...
- 整理:WPF中CommandBindings的用法
原文:整理:WPF中CommandBindings的用法 目的:了解一下CommandBindings.InputBindings.ICommandSource中在WPF中扮演什么样的角色 Comma ...
- (原创)使用C#开发PLC上位机监控系统客户端应用程序
PLC客户端监控系统的特点: 0.客户端系统软件可部署在 多个管理层的PC机上,或者需要部署在距离服务器较远区域的PC机上,通过网线连接到服务器端的交换机. 1应用范围: (1)所有客户端都只有监视功 ...
- 一张图看懂SharpSocket
SharpSocket提供了很多接口和类,他们被良好地组织在一起,通过下面的图片,可以瞬间看懂整个类库的脉络.通过调用各个接口的方法,完成socket通信的功能.
- Socket心跳机制-JS+PHP实现
本文是我在实际工作中用到的Socket通信,关于心跳机制的维护方式,特意总结了一下,希望对朋友们有所帮助. Socket应用:首先Socket 封装了tcp协议的,通过长连接的方式来与服务器通信,是由 ...
- WinExec, ShellExecute,CreateProcess 区别
其中以WinExec最为简单,ShellExecute比WinExec灵活一些,CreateProcess最为复杂. WinExec 有两个参数,前一个指定路径,后一个指定显示方式. ShellExe ...
- 阿里熔断限流Sentinel研究
1. 阿里熔断限流Sentinel研究 1.1. 功能特点 丰富的应用场景:例如秒杀(即突发流量控制在系统容量可以承受的范围).消息削峰填谷.集群流量控制.实时熔断下游不可用应用等 完备的实时监控:S ...
- linux配置iptables
iptables主要用来配置防火墙.其是一个需要特别谨慎设置的东西,服务器不在身边,不要贸然设置,有可能导致无法SSH,那就麻烦了. 1.首先介绍一下指令和相关配置文件 启动指令:service ip ...
- Solr新特性【4.x,5.x,6.x,7.x】
一.Solr4.x新特性 1.近实时搜索 Solr的近实时搜索[Near Real-Time,NRT]功能实现了文档添加到搜索的快速进行,以应对搜索快速变化的数据. 2.原子更新与乐观并发 原子更新功 ...
- pandas 之 group by 过程
import numpy as np import pandas as pd Categorizing a dataset and applying a function to each group ...