[Codeforces 1016F]Road Projects
Description
给你一棵 \(n\) 个节点的树,定义 \(1\) 到 \(n\) 的代价是 \(1\) 到 \(n\) 节点间的最短路径的长度。现在给你 \(m\) 组询问,让你添加一条边权为 \(w\) 的边(不与原图重复),求代价的最大值。询问之间相互独立。
\(1\leq n,m\leq 3\times 10^5\)
Solution
辣鸡老余毁我青春
把 \(1\) 至 \(n\) 的路径提取出来,显然图就变成了一条链加上若干子树。贪心的思想是找这样一组点,满足
- 其所属的子树来自链上两个不同的点(可以选链上的点)
- 一定是该子树内最深的那个点
然后我们可以遍历这条链,找出满足上述所有情况的最大值。最后 \(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的更多相关文章
- Codeforces 626F Group Projects(滚动数组+差分dp)
F. Group Projects time limit per test:2 seconds memory limit per test:256 megabytes input:standard i ...
- Codeforces 543D. Road Improvement (树dp + 乘法逆元)
题目链接:http://codeforces.com/contest/543/problem/D 给你一棵树,初始所有的边都是坏的,要你修复若干边.指定一个root,所有的点到root最多只有一个坏边 ...
- Codeforces 543D Road Improvement
http://codeforces.com/contest/543/problem/D 题意: 给定n个点的树 问: 一开始全是黑边,对于以i为根时,把树边白染色,使得任意点走到根的路径上不超过一条黑 ...
- Codeforces 702D Road to Post Office(模拟 + 公式推导)
题目链接:http://codeforces.com/problemset/problem/702/D 题意: 一个人要去邮局取东西,从家到达邮局的距离为 d, 它可以选择步行或者开车,车每走 k 公 ...
- Codeforces 240E. Road Repairs 最小树形图+输出路径
最小树形图裸题,只是须要记录路径 E. Road Repairs time limit per test 2 seconds memory limit per test 256 megabytes i ...
- Codeforces 729C Road to Cinema(二分)
题目链接 http://codeforces.com/problemset/problem/729/C 题意:n个价格c[i],油量v[i]的汽车,求最便宜的一辆使得能在t时间内到达s,路途中有k个位 ...
- Codeforces 721E Road to Home
题意 输入第一行有4个数,分别为\(L,n,p,t\),分别表示总长度为\(L\)的路,中间有\(n\)个互不相交的区间,现在要用长度为\(p\)的小木棒从左往右铺路(木棒不能被折断,也不能有重叠,且 ...
- Codeforces 543D Road Improvement(树形DP + 乘法逆元)
题目大概说给一棵树,树的边一开始都是损坏的,要修复一些边,修复完后要满足各个点到根的路径上最多只有一条坏的边,现在以各个点为根分别求出修复边的方案数,其结果模1000000007. 不难联想到这题和H ...
- Codeforces 543D Road Improvement(DP)
题目链接 Solution 比较明显的树形DP模型. 首先可以先用一次DFS求出以1为根时,sum[i](以i为子树的根时,满足要求的子树的个数). 考虑将根从i变换到它的儿子j时,sum[i]产生的 ...
随机推荐
- maven解决omitted for duplicate(依赖冲突)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...
- Codeforces 835C-Star sky
题目链接:http://codeforces.com/problemset/problem/835/C 题意:天上有很多星星,每个星星有他自己的坐标和初始亮度,然后每个星星的亮度在一秒内会加一如果大于 ...
- python 实践项目 强密码检测
需求:写一个函数,它使用正则表达式,确保传入的口令字符串是强口令.强口令的定义是:长度不少于 8 个字符,同时包含大写和小写字符,至少有一位数字.你可能需要用多个正则表达式来测试该字符串,以保证它的强 ...
- Python11/26--mysql之视图/触发器/事务/存储过程
视图: 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次用的时候直接使用即可 2.为什么用视图 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何用视图 select * from ...
- Python实例浅谈之三Python与C/C++相互调用
一.问题 Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结. 二.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库比较简单,不经过 ...
- python黑帽子-黑客与渗透测试编程之道(源代码)
链接: https://pan.baidu.com/s/1i5BnB5V 密码: ak9t
- IntelliJ IDEA的破解方法
一.下载并安装, IntelliJ IDEA的官网:https://www.jetbrains.com 下载 下载 下载 二.破解. 百度下载一个 JetbrainsCrack-2.7-release ...
- Scala数组小结
1.定长数组 定长数组:指长度不可变的数组Array. 第一种方式: 先声明一个数组,后初始化该数组: scala> val array = new Array[Double](5) array ...
- 编译与解释(java)
计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序. 翻译的方式有两种,一个是编译,一个是解释.两种方式只是翻译的时间不同 计算机不 ...
- mac下安装安卓开发环境
对于做ios的人来说,安装安卓开发环境,最好是在mac下安装了,我的mac是10.8.2,64位系统的 安卓开发环境需要下面几个东西: 1 jdk(mac下已经默认有了,可以在命令提示符下输入java ...