【CF1016F】Road Projects(贪心)
题意:给你一棵n 个节点的树,定义1到n的代价是1到 n节点间的最短路径的长度。
现在给你 m 组询问,让你添加一条边权为 w 的边(不与原图重复),求代价的最大值。询问之间相互独立。
1≤n,m≤3×1e5,1<=c[i]<=1e9,1<=w<=1e9
思路:网上dalao们的写法好像都和我不太一样……
考虑将1-n路径上所有的点取出,则原树变成了一条链和若干条子树
首先判断以链上某一点为根的子树size是否>=3,若是则可以在其内部连边,对最短路没有影响
若没有则考虑在链上的点或者其延伸出的一个点(size<=2)中取某两个点上连边
预处理出mx[u]代表u除链上儿子的子树最大深度
则对于x,y(x在上y在下)两个点来说相对于原方案,新的方案增加了mx[x]+mx[y]-2*dis[y]的长度
对于固定的y只需要维护mx[x]的前缀最大值
需要注意的是不能连原树中有的边,即mx[x]=dis[x]和mx[y]=dis[y]不能同时成立,否则相当于同时取到链上相邻的两点
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second
#define MP make_pair
#define N 310000
#define M 51
#define MOD 1000000007
#define eps 1e-8
#define pi acos(-1)
#define oo 3e14 struct node
{
int x,cost;
node(int a,int b)
{
x=a;
cost=b;
}
}; ll d[N],mx[N],dis[N];
int flag[N],size[N],fa[N],b[N],q[N];
vector<node>c[N]; void dfs(int u)
{
flag[u]=;
for(int i=;i<=(int)c[u].size()-;i++)
{
int v=c[u][i].x;
if(!flag[v])
{
fa[v]=u;
dis[v]=dis[u]+c[u][i].cost;
dfs(v);
}
}
} void dfs2(int u)
{
flag[u]=size[u]=;
mx[u]=dis[u];
for(int i=;i<=(int)c[u].size()-;i++)
{
int v=c[u][i].x;
if(flag[v]==&&b[v]==)
{
dfs2(v);
size[u]+=size[v];
mx[u]=max(mx[u],mx[v]);
}
}
} int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) c[i].clear();
for(int i=;i<=n-;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
c[x].push_back(node(y,z));
c[y].push_back(node(x,z));
}
memset(flag,,sizeof(flag));
dis[]=;
dfs();
memset(b,,sizeof(b));
int num=;
int k=n;
while(k!=)
{
q[++num]=k;
b[k]=;
k=fa[k];
}
q[++num]=; b[]=;
memset(flag,,sizeof(flag));
for(int i=;i<=num;i++) dfs2(q[i]); int p=;
for(int i=;i<=num;i++)
{
int u=q[i];
if(size[u]>=){p=; break;}
} for(int i=;i<=num/;i++) swap(q[i],q[num-i+]);
ll len=-oo;
for(int i=;i<=num;i++)
{
int u=q[i];
if(i>=)
{
int fa=q[i-];
if(mx[u]>dis[u]) len=max(len,mx[u]-dis[u]*+d[i-]);
else
{
if(mx[fa]>dis[fa]) len=max(len,mx[u]-dis[u]*+d[i-]);
else if(i>=)
{
int x=q[i-];
len=max(len,mx[u]-dis[u]*+d[i-]);
}
}
}
if(i==) d[i]=mx[u];
else d[i]=max(d[i-],mx[u]);
} for(int i=;i<=m;i++)
{
int x;
scanf("%d",&x);
if(p){printf("%lld\n",dis[n]); continue;}
printf("%lld\n",min(dis[n],dis[n]+len+x));
}
return ;
}
【CF1016F】Road Projects(贪心)的更多相关文章
- CF1016F 【Road Projects】
思路 可以考虑另一种想法:因为我们发现,答案是肯定不会大于在原来的树上的最短路径的.所以原来的最短路是(有可能的)最大值! 我们把树变成这样,提取出1~n的路径,方便观看撕烤: (它有个我起的名字,叫 ...
- [Codeforces 1016F]Road Projects
Description 题库链接 给你一棵 \(n\) 个节点的树,定义 \(1\) 到 \(n\) 的代价是 \(1\) 到 \(n\) 节点间的最短路径的长度.现在给你 \(m\) 组询问,让你添 ...
- Educational Codeforces Round 48
题目地址 Edu48 A.Death Note 翻译 你有一个无穷页的本子,每一页可以写\(m\)个名字, 你在第\(i\)天要写\(a_i\)个名字,如果这一页恰好写满了,你就会翻页, 问每天的翻页 ...
- dp or 贪心 --- hdu : Road Trip
Road Trip Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 29 ...
- HDU 1598 find the most comfortable road 并查集+贪心
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1598 find the most comfortable road Time Limit: 1000 ...
- CF1203F2 Complete the Projects (hard version)(结论+背包+贪心)
题目 做法 对于加分的直接贪心 而掉分的用排序后的背包动规 假设有两个物品\((a_1,b_1)(a_2,b_2)\) 选第一个物品后无法选择第二个物品,假设开始值为\(r\):\(r>a_1, ...
- Codeforces1203F2. Complete the Projects (hard version) (贪心+贪心+01背包)
题目链接:传送门 思路: 对于对rating有提升的项目,肯定做越多越好,所以把$b_{i} >= 0$的项目按rating要求从小到大贪心地都做掉,得到最高的rating记为r. 对于剩余的$ ...
- Road to Cinema(贪心+二分)
https://www.cnblogs.com/flipped/p/6083973.html 原博客转载 http://codeforces.com/group/1EzrFFyOc0/co ...
- Codeforces Round #579 (Div. 3) Complete the Projects(贪心、DP)
http://codeforces.com/contest/1203/problem/F1 Examples input 1 - - output 1 YES input 2 - - output 2 ...
随机推荐
- PHP使用redis(一)
1,connect 描述:实例连接到一个Redis.参数:host: string,port: int返回值:BOOL 成功返回:TRUE;失败返回:FALSE <?php $redis = ...
- SSO 单点登录总结(PHP)
本篇文章根据个人理解的知识整理汇总,如有不足之处,请大家多多指正. 单点登录(SSO--Single Sign On)的应用是很普遍的,尤其在大型网站系统中,比如百度,登录百度账号和,再转到百度经验. ...
- &、|、~与&&、||、! 谬误
按位运算符(&.|.~)的操作是被默认为一个二进制的位序列,分别对其中的每个位进行操作. 逻辑运算符(&&.||.!)将操作数当成非真及假,非假及真.通常就是将0当成假,非0即 ...
- 第三章习题 C++ Primer 第六版
1.使用一个整数输入自己的身高(单位为cm),并将此身高转化为米和厘米共同表示的形式,使用下划线字符来指示输入的位置,使用一个const符号常量来表示转换因子. #include<iostrea ...
- HDFS HA(High Availability)高可用性
HDFS HA(High Availability)高可用性 参考文献: 官方文档 全文翻译 Hadoop组件之-HDFS(HA实现细节) 这张图片的个人理解 由于NameNode在Hadoop1只有 ...
- JS:关于JS字面量及其容易忽略的12个小问题
简要 问题1:不能使用typeof判断一个null对象的数据类型 问题2:用双等号判断两个一样的变量,可能返回false 问题3:对于非十进制,如果超出了数值范围,则会报错 问题4:JS浮点数并不精确 ...
- laravel5.5事件广播系统实例laravel-echo + redis + socket.io
目录 1. 广播配置说明 1.1 广播驱动配置 1.2 注册服务提供器 2. 驱动器配置 2.1 安装predis 2.2. 配置服务端 2.2.1 安装方法 2.2.2 初始化服务端 2.2.3 运 ...
- Java - ArrayList List 等迭代集合执行移除(remove) 的正确方法
方法1: List<String> al = new ArrayList<String>(); Iterator<String> it = al.iterator( ...
- C# p-Inovke C++动态链接库
在C++的动态链接库 写了一个测试方法,然后想在C#客户端进行pInvoke调用,始终报异常如下: 试图加载格式不正确的程序. (异常来自 HRESULT:0x8007000B). 最后发现, 需要将 ...
- 【Decision Tree】林轩田机器学习技法
首先沿着上节课的AdaBoost-Stump的思路,介绍了Decision Tree的路数: AdaBoost和Decision Tree都是对弱分类器的组合: 1)AdaBoost是分类的时候,让所 ...