题意:给你一棵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(贪心)的更多相关文章

  1. CF1016F 【Road Projects】

    思路 可以考虑另一种想法:因为我们发现,答案是肯定不会大于在原来的树上的最短路径的.所以原来的最短路是(有可能的)最大值! 我们把树变成这样,提取出1~n的路径,方便观看撕烤: (它有个我起的名字,叫 ...

  2. [Codeforces 1016F]Road Projects

    Description 题库链接 给你一棵 \(n\) 个节点的树,定义 \(1\) 到 \(n\) 的代价是 \(1\) 到 \(n\) 节点间的最短路径的长度.现在给你 \(m\) 组询问,让你添 ...

  3. Educational Codeforces Round 48

    题目地址 Edu48 A.Death Note 翻译 你有一个无穷页的本子,每一页可以写\(m\)个名字, 你在第\(i\)天要写\(a_i\)个名字,如果这一页恰好写满了,你就会翻页, 问每天的翻页 ...

  4. dp or 贪心 --- hdu : Road Trip

    Road Trip Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 29 ...

  5. HDU 1598 find the most comfortable road 并查集+贪心

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1598 find the most comfortable road Time Limit: 1000 ...

  6. CF1203F2 Complete the Projects (hard version)(结论+背包+贪心)

    题目 做法 对于加分的直接贪心 而掉分的用排序后的背包动规 假设有两个物品\((a_1,b_1)(a_2,b_2)\) 选第一个物品后无法选择第二个物品,假设开始值为\(r\):\(r>a_1, ...

  7. Codeforces1203F2. Complete the Projects (hard version) (贪心+贪心+01背包)

    题目链接:传送门 思路: 对于对rating有提升的项目,肯定做越多越好,所以把$b_{i} >= 0$的项目按rating要求从小到大贪心地都做掉,得到最高的rating记为r. 对于剩余的$ ...

  8. Road to Cinema(贪心+二分)

    https://www.cnblogs.com/flipped/p/6083973.html       原博客转载 http://codeforces.com/group/1EzrFFyOc0/co ...

  9. 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 ...

随机推荐

  1. js三目运算符执行多个条件

    三元运算符的结果语句可以执行多个操作,每个操作用逗号分隔就可以,例子如下: var a=1: a>5?(alert(1),alert(2)):(alert(3),alert(4))

  2. 02 mysql 基础二 (进阶)

    mysql 基础二 阶段一 表约束 1.not null 非空约束 例子: create table tb1( id int, name varchar(20) not null ); 注意 空字符不 ...

  3. python——matplotlib图像的基本处理

    1.绘制图像中的点和线 from PIL import Image from pylab import * im = array(Image.open('E:\Python\meinv.jpg')) ...

  4. spark提交运算原理

    前面几天元旦过high了,博客也停了一两天,哈哈,今天我们重新开始,今天我们介绍的是spark的原理 首先先说一个小贴士: spark中,对于var count = 0,如果想使count自增,我们不 ...

  5. Apache服务配置

    Apache 1.安装Apache服务 第1步:把光盘设备中的系统镜像挂载到/media/cdrom目录. [root@zhangjh ~]# mkdir -p /media/cdrom/ [root ...

  6. J.U.C 系列之Atomic原子类

    一 什么是原子类? 所谓原子类必然是具有原子性的类,原子性操作--原子操作,百度百科中给的定义如下 "原子操作(atomic operation)是不需要synchronized" ...

  7. 用for循环计算(1-3+5-7...99)的结果(两种方法)

    1) sum=0 count=1 for i in range(1,100,2): if count % 2==0: sum = sum - i else: sum = sum + i count = ...

  8. HDU 1384 Intervals(差分约束)

    Intervals Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  9. viewpager 无网络的时候滑动异常

    不知道大家有没有遇到过这种情况,就是框架是viewpager+fragment的架构.然后呢,fragment里面是webview.一般情况下,当没有网的时候,webviwe会说什么找不到网页,然后很 ...

  10. Spring自动装配bean

    Spring推荐面向接口编程,这样可以很好的解耦具体的实现类. CompactDisc.class 文件: public interface CompactDisc { void play(); } ...