Description

题库链接

给你一棵 \(n\) 个节点的树,定义 \(1\) 到 \(n\) 的代价是 \(1\) 到 \(n\) 节点间的最短路径的长度。现在给你 \(m\) 组询问,让你添加一条边权为 \(w\) 的边(不与原图重复),求代价的最大值。询问之间相互独立。

\(1\leq n,m\leq 3\times 10^5\)

Solution

辣鸡老余毁我青春

把 \(1\) 至 \(n\) 的路径提取出来,显然图就变成了一条链加上若干子树。贪心的思想是找这样一组点,满足

  1. 其所属的子树来自链上两个不同的点(可以选链上的点)
  2. 一定是该子树内最深的那个点

然后我们可以遍历这条链,找出满足上述所有情况的最大值。最后 \(O(1)\) 回答询问即可。

注意的是要特判 \(1\) 或 \(n\) 结点外连边的情况。

Code

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 300000+5; struct tt {int to, next, cost; } edge[N<<1];
int path[N], top;
int n, m, u, v, c, vis[N], sz[N], flag, f, szf;
ll dist[N], maxn = -1, ans, dis[N]; bool dfs(int u, int fa) {
sz[u] = 1;
for (int v, i = path[u]; i; i = edge[i].next)
if ((v = edge[i].to) != fa) {
dis[v] = dis[u]+edge[i].cost;
if (dfs(v, u)) vis[u] = 1;
else dist[u] = max(dist[u], dist[v]+edge[i].cost), flag += (u == n), f += (u == 1);
sz[u] += sz[v];
}
return vis[u] |= (u == n);
}
void dfs2(int u, int fa) {
for (int v, i = path[u]; i; i = edge[i].next)
if ((v = edge[i].to) != fa && vis[v]) {
if (u == 1) szf = sz[u]-sz[v];
if (dist[fa] > 0) maxn = max(maxn, dist[fa]+dis[fa]);
if (dist[u] > 0) maxn = max(maxn, dis[fa]);
if (maxn != -1 && u != 1) ans = max(ans, maxn+dist[u]+dis[n]-dis[u]);
if (dist[fa] == 0 && fa != 0) maxn = max(maxn, dis[fa]);
dfs2(v, u);
}
if (u == n) {
if (dist[fa] > 0) maxn = max(maxn, dist[fa]+dis[fa]);
if (dist[u] > 0) maxn = max(maxn, dis[fa]);
if (maxn != -1) ans = max(ans, maxn+dist[u]);
}
}
void add(int u, int v, int c) {edge[++top] = (tt){v, path[u], c}; path[u] = top; }
void work() {
scanf("%d%d", &n, &m);
for (int i = 1; i < n; i++) {
scanf("%d%d%d", &u, &v, &c);
add(u, v, c), add(v, u, c);
}
dfs(1, 0); dfs2(1, 0);
while (m--) {
scanf("%d", &c);
if (flag > 1 || sz[n] >= 3) printf("%I64d\n", dis[n]);
else if (f > 1 || szf >= 3) printf("%I64d\n", dis[n]);
else printf("%I64d\n", min(c+ans, dis[n]));
}
}
int main() {work(); return 0; }

[Codeforces 1016F]Road Projects的更多相关文章

  1. Codeforces 626F Group Projects(滚动数组+差分dp)

    F. Group Projects time limit per test:2 seconds memory limit per test:256 megabytes input:standard i ...

  2. Codeforces 543D. Road Improvement (树dp + 乘法逆元)

    题目链接:http://codeforces.com/contest/543/problem/D 给你一棵树,初始所有的边都是坏的,要你修复若干边.指定一个root,所有的点到root最多只有一个坏边 ...

  3. Codeforces 543D Road Improvement

    http://codeforces.com/contest/543/problem/D 题意: 给定n个点的树 问: 一开始全是黑边,对于以i为根时,把树边白染色,使得任意点走到根的路径上不超过一条黑 ...

  4. Codeforces 702D Road to Post Office(模拟 + 公式推导)

    题目链接:http://codeforces.com/problemset/problem/702/D 题意: 一个人要去邮局取东西,从家到达邮局的距离为 d, 它可以选择步行或者开车,车每走 k 公 ...

  5. Codeforces 240E. Road Repairs 最小树形图+输出路径

    最小树形图裸题,只是须要记录路径 E. Road Repairs time limit per test 2 seconds memory limit per test 256 megabytes i ...

  6. Codeforces 729C Road to Cinema(二分)

    题目链接 http://codeforces.com/problemset/problem/729/C 题意:n个价格c[i],油量v[i]的汽车,求最便宜的一辆使得能在t时间内到达s,路途中有k个位 ...

  7. Codeforces 721E Road to Home

    题意 输入第一行有4个数,分别为\(L,n,p,t\),分别表示总长度为\(L\)的路,中间有\(n\)个互不相交的区间,现在要用长度为\(p\)的小木棒从左往右铺路(木棒不能被折断,也不能有重叠,且 ...

  8. Codeforces 543D Road Improvement(树形DP + 乘法逆元)

    题目大概说给一棵树,树的边一开始都是损坏的,要修复一些边,修复完后要满足各个点到根的路径上最多只有一条坏的边,现在以各个点为根分别求出修复边的方案数,其结果模1000000007. 不难联想到这题和H ...

  9. Codeforces 543D Road Improvement(DP)

    题目链接 Solution 比较明显的树形DP模型. 首先可以先用一次DFS求出以1为根时,sum[i](以i为子树的根时,满足要求的子树的个数). 考虑将根从i变换到它的儿子j时,sum[i]产生的 ...

随机推荐

  1. JS判断是否有js、css文件的引入方法

    在页面头部有个 <script type="text/javascript" src="abc.js"></script> <li ...

  2. Nodejs之路:异步I/O的过程

    对于Node中的异步I/O调用,从发出调用到回调执行,看起来像普通的js异步,但是流程却和普通js那些消息队列完全不同,整个过程经历了哪些? 下面以Windows平台下为例: 一,异步调用第一阶段: ...

  3. spring与junit整合测试

    1.导包4+2+aop+test 2.配置注解 3.测试

  4. suse下修改主机名

    export HOSTNAME=主机名 echo $HOSTNAME>/etc/HOSTNAME /etc/rc.d/boot.localnet stop /etc/rc.d/boot.loca ...

  5. centos7安装python3.6后导致防火墙功能无法正常工作的解决办法

    问题:因为默认python版本被设置成了python3.6,而进行防火墙的指令操作频频报错. Jul 19 16:30:51 localhost.localdomain systemd[1]: Sta ...

  6. 子div撑不开父div

    方法一:推荐 设置父div的overflow:hidden; 方法二: 父div结束前增加一个空div style=”clear:both;” .clear { clear:both; } <d ...

  7. Linux下nautilus的右键快捷菜单项设置

    某一天我的Linux更新完后, 我照常在文件夹下点击右键想打开终端, 却发现右键快捷菜单没有Open in terminal的菜单项了. 在网上查找了一下, 结合自己系统的情况发现了解决办法. 由于我 ...

  8. java时间与js时间

    这是一个由java获取的系统时间与js获取的系统时间不一致导致的测试缺陷 定义方式: java Date date = new Date(); js var Date date2 = new Date ...

  9. Python-字典(dict)

    字典是一种key-value的数据类型,字典里必须写Key和value: 字典的优点是取数方便和速度快. 字典的定义使用大括号{ },每个值用“,”隔开,key和value使用“:”分隔. value ...

  10. OpenCV基础知识介绍

    1.图像与矩阵 一般来说,图像是一个标准的矩形,有着宽度(width)和高度(height).而矩阵有着行(row)和列(column),矩阵的操作在数学和计算机中的处理都很常见且成熟,于是很自然的就 ...