\(\mathcal{Description}\)

  Link.

  给定一棵含 \(n\) 个结点的树,双向边权不相同。\(q\) 次询问,每次询问在树上标记 \(e\) 个点,标记的价值为所有趋向于某个标记点的有向边权值之和,求价值的最大值。

  \(q\le n\le2\times10^5\)。

\(\mathcal{Solution}\)

  \(e=1\text{ or }2\) 的时候可以直接换根求解。需要强调的是,当确定一个被标记的根时,其余标记点的贡献为根到这个标记点的有向路径长度(取并)。接下来引入一些结论。首先有:

  对于一棵根被钦定标记的树(\(e=1\)),当 \(e=k<n\) 时,一定能通过标记深度最深的结点使得其成为 \(e=k\) 时的最优解。

  不难意会。(

  由此可以推出一个关键的结论:

  对于 \(k>2\),\(e=k\) 时的最优解必然通过在某个 \(e=k-1\) 时的最优解的基础上新标记一个点得到。

  记 \(e=k\) 时某个最优解标记点集合为 \(S\),\(e=k+1\) 时任一最优解的标记点集合为 \(T\),考虑反证,若不存在 \(S\sub T\):

  • 若 \(S\cap T\neq\varnothing\),取一个 \(r\in S\cap T\),标记并作为树根。由上一个结论,矛盾。
  • 若 \(S\cap T=\varnothing\),考虑把 \(T\) 中的一个结点丢到 \(S\) 中,此时 \(S\) 不会比 \(T\) 劣。

  所以,以 \(e=2\) 时的一个标记点为根,令每片叶子的权值为其保持作为子树最深点,向上能爬的距离。排序取前 \(k\) 大之和加上一些常数就是 \(e=k\) 的答案。复杂度 \(\mathcal O(n\log n)\)。

\(\mathcal{Code}\)

/* Clearink */

#include <cstdio>
#include <algorithm> #define rep( i, l, r ) for ( int i = l, repEnd##i = r; i <= repEnd##i; ++i )
#define per( i, r, l ) for ( int i = r, repEnd##i = l; i >= repEnd##i; --i ) typedef long long LL;
typedef std::pair<int, LL> PIL; inline int rint() {
int x = 0, s = getchar();
for ( ; s < '0' || '9' < s; s = getchar() );
for ( ; '0' <= s && s <= '9'; s = getchar() ) x = x * 10 + ( s ^ '0' );
return x;
} template<typename Tp>
inline void wint( Tp x ) {
if ( x < 0 ) putchar( '-' ), x = -x;
if ( 9 < x ) wint( x / 10 );
putchar( x % 10 ^ '0' );
} inline LL lmax( const LL a, const LL b ) { return a < b ? b : a; }
inline void chkmax( LL& a, const LL b ) { a < b && ( a = b, 0 ); } const int MAXN = 2e5;
const LL LINF = 1ll << 60;
int n, ecnt = 1, head[MAXN + 5], rt;
LL all, upsum, wgt[MAXN + 5];
struct Edge { int to, val, nxt; } graph[MAXN * 2 + 5]; inline void link( const int s, const int t, const int w ) {
graph[++ecnt] = { t, w, head[s] };
head[s] = ecnt;
} namespace Subtask23 { int siz[MAXN + 5], root;
LL sum[MAXN + 5], mx[MAXN + 5], sm[MAXN + 5], ans[2]; inline void init( const int u, const int fa ) {
siz[u] = 1, mx[u] = 0, sm[u] = -LINF;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ fa ) {
init( v, u );
siz[u] += siz[v], sum[u] += sum[v] + graph[i ^ 1].val;
LL d = mx[v] + graph[i].val;
if ( mx[u] < d ) sm[u] = mx[u], mx[u] = d;
else if ( sm[u] < d ) sm[u] = d;
}
}
} inline void solve( const int u, const int fa, const LL ups, const LL upx ) {
chkmax( ans[0], sum[u] + ups );
LL tmp = sum[u] + ups + lmax( upx, mx[u] );
if ( ans[1] < tmp ) root = u, ans[1] = tmp;
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ fa ) {
int w1 = graph[i].val, w2 = graph[i ^ 1].val;
LL ns = ups + sum[u] - sum[v] - w2 + w1;
LL nx = lmax( upx, mx[v] + w1 < mx[u] ? mx[u] : sm[u] ) + w2;
solve( v, u, ns, nx );
}
}
} inline void main() {
init( 1, 0 );
solve( 1, 0, 0, 0 );
} } // namespace Subtask23. inline PIL init( const int u, const int fa ) {
PIL ret( u, 0 );
for ( int i = head[u], v; i; i = graph[i].nxt ) {
if ( ( v = graph[i].to ) ^ fa ) {
PIL tmp( init( v, u ) );
upsum += graph[i ^ 1].val;
wgt[tmp.first] += graph[i].val;
if ( tmp.second + graph[i].val > ret.second ) {
ret = { tmp.first, tmp.second + graph[i].val };
}
}
}
return ret;
} int main() {
freopen( "city.in", "r", stdin );
freopen( "city.out", "w", stdout );
n = rint();
rep ( i, 2, n ) {
int u = rint(), v = rint(), a = rint(), b = rint();
all += a + b;
link( u, v, a ), link( v, u, b );
}
Subtask23::main();
rt = Subtask23::root;
init( rt, 0 );
// printf( "root is %d: ", rt );
// rep( i, 1, n ) printf( "%lld ", wgt[i] );
// puts( "" );
std::sort( wgt + 1, wgt + n + 1, []( const LL a, const LL b ) {
return a > b;
} );
rep( i, 1, n ) wgt[i] += wgt[i - 1];
for ( int q = rint(), e; q--; ) {
e = rint();
wint( all - ( e < 2 ? Subtask23::ans[0] :
upsum + wgt[e - 1] ) ), putchar( '\n' );
}
return 0;
}

Solution -「JOISC 2019」「LOJ #3036」指定城市的更多相关文章

  1. 【LOJ】#3036. 「JOISC 2019 Day3」指定城市

    LOJ#3036. 「JOISC 2019 Day3」指定城市 一个点的可以dp出来 两个点也可以dp出来 后面的就是在两个点的情况下选一条最长的链加进去,用线段树维护即可 #include < ...

  2. 【LOJ】#3034. 「JOISC 2019 Day2」两道料理

    LOJ#3034. 「JOISC 2019 Day2」两道料理 找出最大的\(y_{i}\)使得\(sumA_{i} + sumB_{y_i} \leq S_{i}\) 和最大的\(x_{j}\)使得 ...

  3. 【LOJ】#3032. 「JOISC 2019 Day1」馕

    LOJ#3032. 「JOISC 2019 Day1」馕 处理出每个人把馕切成N段,每一段快乐度相同,我们选择第一个排在最前的人分给他的第一段,然后再在未选取的的人中选一个第二个排在最前的切一下,并把 ...

  4. 【LOJ】#3033. 「JOISC 2019 Day2」两个天线

    LOJ#3033. 「JOISC 2019 Day2」两个天线 用后面的天线更新前面的天线,线段树上存历史版本的最大值 也就是线段树需要维护历史版本的最大值,后面的天线的标记中最大的那个和最小的那个, ...

  5. 【LOJ】#3031. 「JOISC 2019 Day1」聚会

    LOJ#3031. 「JOISC 2019 Day1」聚会 听说随机可过? 我想了很久想了一个不会被卡的做法,建出前\(u - 1\)个点的虚树,然后找第\(u\)个点的插入位置,就是每次找一条最长链 ...

  6. 【LOJ】#3030. 「JOISC 2019 Day1」考试

    LOJ#3030. 「JOISC 2019 Day1」考试 看起来求一个奇怪图形(两条和坐标轴平行的线被切掉了一个角)内包括的点个数 too naive! 首先熟练的转化求不被这个图形包含的个数 -- ...

  7. 「JOISC 2019 Day3」穿越时空 Bitaro

    「JOISC 2019 Day3」穿越时空 Bitaro 题解: ​ 不会处理时间流逝,我去看了一眼题解的图,最重要的转换就是把(X,Y)改成(X,Y-X)这样就不会斜着走了. ​ 问题变成二维平面上 ...

  8. @loj - 3039@ 「JOISC 2019 Day4」蛋糕拼接 3

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 今天是 IOI 酱的生日,所以她的哥哥 JOI 君给她预定了一个 ...

  9. 「JOISC 2019 Day4」蛋糕拼接 3

    loj 3039 NKOJ Description \(n\)个蛋糕,每个蛋糕有\(w_i,h_i\).选\(m\)个蛋糕满足\(\sum\limits_{j=1}^mw_{k_j}-\sum\lim ...

随机推荐

  1. 访问 远程 tomcat 的管理页面 /manager/html 提示 403 的具体解决操作

    1.前言 我在阿里云服务器放了个tomcat ,启动后 ,访问 /manager/html提示403无权访问 原因是 tomcat默认仅仅允许本地的浏览器访问,有ip限制 需要将ip限制去除 顺便把账 ...

  2. 05.python解析式与生成器表达式

    解析式和生成器表达式 列表解析式 列表解析式List Comprehension,也叫列表推导式 #生成一个列表,元素0-9,将每个元素加1后的平方值组成新的列表 x = [] for i in ra ...

  3. python 读取配置文件ini ---ConfigParser

    Python读取ini文件需要用到 ConfigParser 模块 关于ConfigParser模块的介绍详情请参照官网解释:https://docs.python.org/2.7/library/c ...

  4. Blinn-Phong反射模型实践(web实现)

    Blinn-Phong反射模型实践(web实现) games101 第四次作业 最终完成带贴图的 Blinn-Phong 模型,产生光照效果 完成了 不带贴图的 Blinn-Phone 反射模型 带贴 ...

  5. 使用.NET 6开发TodoList应用(31)——实现基于Github Actions和ACI的CI/CD

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求和目标 在这个系列的最后一节中,我们将使用GitHub Actions将TodoList应用部署到Azure Container ...

  6. 【解决了一个小问题】golang build中因为缓存文件损坏导致的编译错误

    编译的过程中出现了一个吓人的错误: GOROOT=C:\Go #gosetup GOPATH=C:\Users\ahfuzhang\go #gosetup C:\Go\bin\go.exe mod t ...

  7. 使用Cesium Stories来可视化时序数据

    Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ Cesium可以用来可视化随时间变化的数据,无论是跨越数百年的地 ...

  8. Linux深入探索04-Bash shell

    ----- 最近更新[2021-12-30]----- 本文目录结构预览: 一.简介 二.shell 变量 1.查看变量 2.变量类型 3.变量操作 4.系统常见的全局变量 三.shell 选项 1. ...

  9. APP 性能分析工作台——你的最佳桌面端性能分析助手

    目前 MARS-App 性能分析工作台版本为开发者提供Fastbot桌面版的服务. 旨在帮助开发者们更快.更便捷地开启智能测试之旅,成倍提升稳定性测试的效率. 作者:字节跳动终端技术--王凯 背景 F ...

  10. python07day

    回顾 id == is: ==: 数值是否相同 is: 内存地址是否相同 id: 获取对象的内存地址 代码块: 一个文件.交互式命令一行都是一个代码块 同一代码块下缓存机制(字符串驻留机制) 所有数字 ...