#\(\mathcal{\color{red}{Description}}\)

\(Link\)

在一棵带有边权的树上,可以选择使一条边权为零。然后对于所有\(M\)条链,使其链长最大值最小。

#\(\mathcal{\color{red}{Solution}}\)

……还是老方法,先分析贪心是否可行\(->\)不可行。再分析状态如何定义\(->\)不可定义。最后看比赛难度\(->NOIP\)。得出结论:不是线性规划而是二分答案

嗯,好的,在这之后我们就可以愉悦地二分答案——二分链长最大值最小值,那我们接下来就要考虑如何\(check\)了。我们思考二分出的最长链的长度之后,我们要找一条大于二分出来的长度的链的公共边,让它变成零——设窝萌二分出的链长是\(k\),大于\(k\)的链有\(s\)条,那么我们考虑这\(s\)条可能有\(n(0 \leq n \leq m)\)条公共边,我们选择当\(n\)不为零的时候直接选一条最大的公共边,让最长的链减去这条边的权值,观察其是否\(\leq\)我们二分得到的\(k\),如果是就\(return \ \ 1\)调整\(r\)了;那如果是\(n=0\),这种方案一定会无从下手,因为作为最终答案来讲,若最短时间为\(T\),那么所有原来权值大于\(T\)的边一定有起码一条公共边,所以调整\(l\),直至二分结束即可。

嗯……一二分答案就蒙○……

哦对,链长我们是可以预处理出来的\(qwq\)

#include <cmath>
#include <cstdio>
#include <iostream>
#define MAXN 600010 using namespace std ;
struct edge{
int to, next, v ;
}e[MAXN] ; int cnt, head[MAXN] ;
int LcA[MAXN], fa[MAXN][32], dep[MAXN], Len[MAXN] ;
int l = 1, r, mid, i, j, A, B, C, N, M, Up, Max, pre, num ;
int dif[MAXN], S[MAXN], T[MAXN], dis[MAXN], edges[MAXN], res, ans ; inline int qr(){
int k = 0 ; char c = getchar() ;
while(!isdigit(c)) c = getchar() ;
while(isdigit(c)) k = (k << 1) + (k << 3) + c - 48, c = getchar() ;
return k ;
}
inline void add(int u, int v, int w){
e[++ cnt].to = v, e[cnt].v = w ;
e[cnt].next = head[u], head[u] = cnt ;
e[++ cnt].to = u, e[cnt].v = w ;
e[cnt].next = head[v], head[v] = cnt ;
}
void _build(int deep, int now, int f){
fa[now][0] = f ; dep[now] = deep ;
for(int k = head[now]; k ;k = e[k].next){
if(e[k].to == f) continue ;
edges[e[k].to] = e[k].v ;
Len[e[k].to] = Len[now] + edges[e[k].to] ;
_build(deep + 1, e[k].to, now) ;
}
}
inline void _get(int now){
for(int k = head[now]; k ; k = e[k].next){
if(e[k].to == fa[now][0]) continue ;
_get(e[k].to) ;
dif[now] += dif[e[k].to] ;
}
if(dif[now] == num && edges[now] > res) res = edges[now] ;
}
inline void init(){
Up = log(N) / log(2) + 1 ;
for(i = 1; i <= Up; i ++)
for(j = 1; j <= N; j ++)
fa[j][i] = fa[fa[j][i - 1]][i - 1] ;
}
inline int LCA(int u, int v){
if(dep[u] < dep[v]) swap(u, v) ;
pre = dep[u] - dep[v] ;
for(j = 0; j <= Up; ++ j) if((1 << j) & pre) u = fa[u][j] ;
if(u == v) return u ;
for(j = Up; j >= 0; -- j) if(fa[u][j] != fa[v][j]) u = fa[u][j], v = fa[v][j] ;
return fa[v][0] ;
}
inline bool check(int x){
fill(dif + 1, dif + N + 1, 0) ; num = 0 ; res = 0 ;
for(i = 1; i <= M; ++ i)
if(dis[i] > x)
num ++, dif[S[i]] ++, dif[T[i]] ++, dif[LcA[i]] -= 2 ;
_get(1) ;
if(Max - res > x) return 0 ;
return 1 ;
} int main(){
N = qr(), M = qr() ;
for(i = 1; i < N; ++ i)
A = qr(), B = qr(), C = qr(), add(A, B, C);
_build(1, 1, 0) ; init() ;
for(i = 1; i <= M; ++ i){
S[i] = qr(), T[i] = qr(), LcA[i] = LCA(S[i], T[i]) ;
dis[i] = Len[S[i]] + Len[T[i]] - (Len[LcA[i]] << 1) ;
Max = max(dis[i], Max) ;
}
r = Max ;
while(l <= r){
mid = (l + r) >> 1 ;
if(check(mid)) r = mid - 1, ans = mid;
else l = mid + 1 ;
}
cout << ans ;
}

本题心得:

\(1\)、有时候单纯暴力的二分不是很好做……但是我们如果换种思路思考二分的话,他的显然性就很显然。

\(2\)、嗯,我还是太弱了,未来的路好长啊……

随机推荐

  1. 【PyQt5 学习记录】008:改变窗口样式之二

    super(MainWindow, self).__init__(parent, flags=Qt.Widget) 首先需要关闭窗口的默认样式,以方便定时想要的样式: self.setWindowFl ...

  2. Unable to load script from assets 'index.android.bundle' 出错?

    野路子太多,坑人真的!F**k 言归正传,当你运行 react native 程序的时候出现这个错误 ,如果您使用Windows,请按以下方式运行命令,或者如果出现错误“无法找到条目文件index.a ...

  3. js面向对象设计之function类

    本文仅探讨如何合理的使用 function 在 javascript中实现一个面向对象设计的类.总所周知,javascript 并不能实现一个真正意义上的类,比如 protect 比如 函数重载.下面 ...

  4. CSS选择器之伪类选择器(元素)

    :first-child 选择某个元素的第一个子元素(IE6不支持) :last-child 选择某个元素的最后一个子元素 :first-of-type [CSS3]选择一个上级元素下的第一个同类子元 ...

  5. Java 简化版学生管理系统(IO版)

    Student management system   学生管理系统IO版 详细知识点可参考一下几篇文章 常用API Java 之ArrayList集合及应用 Java 之IO流及应用 Compreh ...

  6. 一步一步pwn路由器之radare2使用实战

    前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 前文讲了一些 radare2 的特性相关的操作方法.本文以一个 c ...

  7. 如何优雅使用Coursera ? —— Coursera 视频缓冲 & 字幕遮挡

    Coursera 视频缓冲 其实这个问题的根本是coursera上视频源d3c33hcgiwev3.cloudfront.net被墙,而ss的pac并未及时更新所导致的. 1 chrome 插件 - ...

  8. Automate the Sizing of your SGA in Oracle 10g

    How much memory does each of the individual components of the SGA need? Oracle now has methods to de ...

  9. Elasticsearch安装记录

    一 安装部分 1.新建用户 elasticsearch不能使用root身份执行 adduser esuser passwd esuser 2.赋予权限 切换到root chown -R esuser ...

  10. 用UITextView模拟UITextField的placeHolder

    用UITextView模拟UITextField的placeHolder 效果: 源码: // // ViewController.m // TextView // // Created by You ...