题目描述

小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的迷你挑战。

游戏中有一个叫做“LCT” 的挑战,它的规则是这样子的:现在有一个N 个点的 树(Tree),每条边有一个整数边权vi ,若vi >= 0,表示走这条边会获得vi 的收益;若vi < 0 ,则表示走这条边需要支付- vi 的过路费。小L 需要控制主角Link 切掉(Cut)树上的 恰好K 条边,然后再连接 K 条边权为 0 的边,得到一棵新的树。接着,他会选择树上的两个点p; q ,并沿着树上连接这两点的简单路径从p 走到q ,并为经过的每条边支付过路费/ 获取相应收益。

海拉鲁大陆之神TemporaryDO 想考验一下Link。他告诉Link,如果Link 能切掉 合适的边、选择合适的路径从而使 总收益 - 总过路费最大化的话,就把传说中的大师之剑送给他。

小 L 想得到大师之剑,于是他找到了你来帮忙,请你告诉他,Link 能得到的 总收益 - 总过路费最大是多少。

输入输出格式

输入格式:

从文件lct.in 中读入数据。

输入第一行包含两个正整数N; K,保证0 <= K < N <= 3* 10^5105 。

接下来N - 1 行,每行包含三个整数xi; yi; vi,表示第i 条边连接图中的xi; yi 两点, 它的边权为vi。

输出格式

输出到文件lct.out 中。

输出一行一个整数,表示答案。

输入输出样例

输入样例#1: 复制

5 1
1 2 3
2 3 5
2 4 -3
4 5 6
输出样例#1: 复制

14

说明

【样例1 解释】

一种可能的最优方案为:切掉(2; 4; ?3) 这条边,连接(3; 4; 0) 这条边,选择(p; q) = (1; 5)。

• 对于10% 的数据,k = 0 ;

• 对于另外10% 的数据,k = 1 ;

• 对于另外15% 的数据,k = 2 ;

• 对于另外25% 的数据,k <= 100 ;

• 对于其他数据,没有特殊约定。

对于全部的测试数据,保证有1 <= N <= 3 * 10^5105 ; 1 <= xi; yi <= N; |vi| <= 10^6106 。

【提示】

题目并不难。

当时在考场上,,只会$k=0$还挂了一个点。。

题目等价于:在树上选择$k+1$条不相交的链,使其权值和最大。

考虑树形DP(以下的$k$均为$k+1$)

一个很直观的想法是用$f[i][j]$表示第$i$个节点,子树中选了$j$条链的最大价值。

但这样是无法转移的,因此我们要考虑到根节点的情况,

令$f[0/1/2][i][j]$表示$i$号节点的子树中选了$j$条链,根节点不在任何一条链中/作为链的端点/作为两条链的端点的最大值。

更新的时候分三种情况讨论。

但是这样复杂度是$O(N*K)$的,考虑继续优化。

看到这种带$k$限制类的问题,我们尝试wqs二分

按照套路,我们观察$f$数组在不同的$k$下的最优解,不难发现函数是上凸的。严格证明不会,自己意会一下吧。。

按照套路,二分一个边权,加到每条边上,我们可以通过控制边权来控制$k$的大小。如果边权都很小,肯定是少选几条链比较优,如果边权比较大,肯定是多选几条优。

按照套路,如果我们二分到一个边权,在这里恰好选了$k$条链,那么这种选法就是最优的。

判断的时候不需要枚举$k$,因此DP一遍的复杂度为$O(N)$,总复杂度为$O(NlogV)$

还有就是这玩意儿二分的边界比较诡异。。。

// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#define Pair pair<int, int>
#define int long long
const int MAXN = * 1e5 + ;
using namespace std;
inline int read() {
char c = getchar(); int x = , f = ;
while(c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * f;
}
struct Node {
int x, y;//x :权值 y:数目
bool operator < (const Node &rhs) const {
return this -> x == rhs.x ? this -> y > rhs.y : this -> x < rhs.x;//tag
}
Node operator + (const Node &rhs) const {
return (Node) {x + rhs.x, y + rhs.y};
}
Node operator + (const int &rhs) const {
return (Node) {x + rhs, y};
}
}f[][MAXN];
int N, K;
struct Edge {
int u, v, w, nxt;
}E[MAXN << ];
int head[MAXN], num = ;
inline void AddEdge(int x, int y, int z) {
E[num] = (Edge) {x, y, z, head[x]};
head[x] = num++;
}
int mid;
Node Plus(Node a) {
return (Node){a.x - mid, a.y + };
}
void dfs(int x, int fa) {
f[][x] = max(f[][x], (Node) {-mid, });
for(int i = head[x]; i != -; i = E[i].nxt) {
int v = E[i].v;
if(v == fa) continue;
dfs(v, x);
f[][x] = max(f[][x] + f[][v], Plus(f[][x] + f[][v] + E[i].w));//把根与子树连起来,会增加一条链
f[][x] = max(f[][x] + f[][v], f[][x] + f[][v] + E[i].w);
f[][x] = f[][x] + f[][v];
//printf("%d %d %d\n", f[2][x].x, f[1][x].x, f[0][x].x);
}
f[][x] = max(f[][x], max(Plus(f[][x]), f[][x]));
}
main() {
#ifdef WIN32
freopen("a.in", "r", stdin);
#endif
memset(head, -, sizeof(head));
N = read(); K = read() + ;
int l = , r = ;
for(int i = ; i < N; i++) {
int x = read(), y = read(), z = read();
AddEdge(x, y, z); AddEdge(y, x, z);
r += abs(z);
}
l = -r;
while(l <= r) {
mid = (l + r) >> ;
memset(f, , sizeof(f));
dfs(, );
if(f[][].y <= K) r = mid - ;
else l = mid + ;
}
mid = l; memset(f, , sizeof(f));
dfs(, );
printf("%lld", f[][].x + mid * K);
return ;
}

洛谷P4383 [八省联考2018]林克卡特树lct(DP凸优化/wqs二分)的更多相关文章

  1. 洛谷 4383 [八省联考2018]林克卡特树lct——树形DP+带权二分

    题目:https://www.luogu.org/problemnew/show/P4383 关于带权二分:https://www.cnblogs.com/flashhu/p/9480669.html ...

  2. 洛谷.4383.[八省联考2018]林克卡特树lct(树形DP 带权二分)

    题目链接 \(Description\) 给定一棵边带权的树.求删掉K条边.再连上K条权为0的边后,新树的最大直径. \(n,K\leq3\times10^5\). \(Solution\) 题目可以 ...

  3. dp凸优化/wqs二分学习笔记(洛谷4383 [八省联考2018]林克卡特树lct)

    qwq 安利一个凸优化讲的比较好的博客 https://www.cnblogs.com/Gloid/p/9433783.html 但是他的暴力部分略微有点问题 qwq 我还是详细的讲一下这个题+这个知 ...

  4. P4383 [八省联考2018]林克卡特树lct

    题目链接 题意分析 一句话题意就是 : 让你选出\((k+1)\)条不相交的链 使得这些链的边权总和最大 (这些链可以是点) 我们考虑使用树形\(DP\) \(dp[i][j][0/1/2]\)表示以 ...

  5. P4383 [八省联考2018]林克卡特树lct 树形DP+凸优化/带权二分

    $ \color{#0066ff}{ 题目描述 }$ 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的 ...

  6. P4383 [八省联考2018]林克卡特树 树形dp Wqs二分

    LINK:林克卡特树 作为树形dp 这道题已经属于不容易的级别了. 套上了Wqs二分 (反而更简单了 大雾 容易想到还是对树进行联通情况的dp 然后最后结果总和为各个联通块内的直径. \(f_{i,j ...

  7. LuoguP4383 [八省联考2018]林克卡特树lct

    LuoguP4383 [八省联考2018]林克卡特树lct https://www.luogu.org/problemnew/show/P4383 分析: 题意等价于选择\(K\)条点不相交的链,使得 ...

  8. [八省联考2018]林克卡特树lct——WQS二分

    [八省联考2018]林克卡特树lct 一看这种题就不是lct... 除了直径好拿分,别的都难做. 所以必须转化 突破口在于:连“0”边 对于k=0,我们求直径 k=1,对于(p,q)一定是从p出发,走 ...

  9. luoguP4383 [八省联考2018]林克卡特树(树上dp,wqs二分)

    luoguP4383 [八省联考2018]林克卡特树(树上dp,wqs二分) Luogu 题解时间 $ k $ 条边权为 $ 0 $ 的边. 是的,边权为零. 转化成选正好 $ k+1 $ 条链. $ ...

随机推荐

  1. ArcGIS DataStore手册——管理篇

    第二章:ArcGIS DataStore管理维护 1.备份管理 备份的目的在于发生原始数据损坏或其他突发情况时,可避免数据丢失,并可快速的使用备份数据来恢复,以保证服务仍可使用. 单机模式下,可使用D ...

  2. Apache服务器运维笔记(5)----容器的处理顺序

    容器在配置文件中是可以多次使用的,同时也可以嵌套使用,但是 Apache 在处理容器时却是有一定顺序的,因此在编写容器配置时需要按照一定的顺序来进行,否则Apache处理的结果很可能不是管理员想要的. ...

  3. Python 2 和Python 3的区别

    print input urlopen print print在版本2的使用方法是: print 'this is version 2' 也可以是 print('this is version 2') ...

  4. 3 TFRecord样例程序实战

    将图片数据写入Record文件 # 定义函数转化变量类型. def _int64_feature(value): return tf.train.Feature(int64_list=tf.train ...

  5. android测试Code

    <!--android:layout_alignParentTop="true"--><com.koooke.platform.View.CenterImage ...

  6. 【NLP汉语自然语言处理与实践】分词_笔记

    一.两种分词标准: 1. 粗粒度. 将词作为最小基本单位.比如:浙江大学. 主要用于自然语言处理的各种应用. 2. 细粒度. 不仅对词汇继续切分,也对词汇内部的语素进行切分.比如:浙江/大学. 主要用 ...

  7. Doing Research Needs Efforts

    What is research?   From YouTube Video or baiduyun Links What does not? spend many hours before you ...

  8. c# HttpWebRequest与HttpWebResponse

    [转]c# HttpWebRequest与HttpWebResponse 绝技 如果你想做一些,抓取,或者是自动获取的功能,那么就跟我一起来学习一下Http请求吧. 本文章会对Http请求时的Get和 ...

  9. 深入理解JNI 邓平凡

    深入理解JNI 邓凡平 1)使用的时候 :加载libmedia_jni.so 并接着调用JNI_Onload->register_android_media_MediaScanner动态注册JN ...

  10. [EffectiveC++]item35:考虑virtual函数以外的其他选择

    本质上是说了:   Template Pattern & Strategy Pattern 详细见<C++设计模式 23种设计模式.pdf 55页> 宁可要组合 不要继承. ——— ...