xsy 1790 - 不回头的旅行
from NOIP2016模拟题28
Description
一辆车,开始没油,可以选择一个点(加油站)出发
经过一个点i可加g[i]的油,走一条边减少len的油
没油的时候车就跪了
特别的,跪在加油站上可以加油继续走
给出一棵树,求最多可以走过多少个点
Analysis
点分治很明显的,只是dfs要点技巧
求出从根往下走到某个点的深度及需要的油
求出从某个点往上走到根的深度及提供的油
注意要同样的两个端点,不同方向走答案不同
所以点分时要扫两次
向下
每个点到根的消耗/剩余会长得像心电图

我们只要保证最低点>=0就好
向上
我们记录一个mx表示每个点到上一个可到根的点的消耗/剩余
每次从mx=0的可到根点x出发会经过如图

轨迹到达下一个mx>=0的点
则那个点可以到x
(旋转180°,改下0点)就变成从下面出发了
同时要把mx变回0
Code
#include <cstdio>
#include <cstdlib>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <algorithm>
using namespace std;
const int INF=2147483647;
const int M=100007;
inline int rd(){
int x=0;bool f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(;isdigit(c);c=getchar()) x=x*10+c-48;
return f?x:-x;
}
int n;
int val[M];
int g[M],te;
struct edge{int y,d,next;}e[M<<1];
void addedge(int x,int y,int z){
e[++te].y=y;e[te].d=z;e[te].next=g[x];g[x]=te;
}
struct node{
int y,d;
node(int yy=0,int dd=0){y=yy;d=dd;}
}que[M];
int tq;
int vis[M];
int sz[M];
int mi,size,rt;
int a[M];
int ans=0;
void getsz(int x,int fa){
sz[x]=1;
int p,y;
for(p=g[x];p;p=e[p].next)
if(!vis[y=e[p].y]&&y!=fa){
getsz(y,x);
sz[x]+=sz[y];
}
}
void getrt(int x,int fa){
int f,p,y;
f=size-sz[x];
for(p=g[x];p;p=e[p].next)
if(!vis[y=e[p].y]&&y!=fa){
getrt(y,x);
f=max(f,sz[y]);
}
if(f<mi) mi=f,rt=x;
}
void find(int dep,int supply){
int l=1,r=size,mid;
while(l<r){
mid=(l+r)/2 +1;
if(a[mid]<=supply) l=mid;
else r=mid-1;
}
ans=max(ans,l+dep);
}
void getup(int x,int fa,int dep,int nw,int mn){
if(mn>=0){
find(dep,nw);
mn=0;
}
int p,y;
for(p=g[x];p;p=e[p].next)
if(!vis[y=e[p].y]&&y!=fa)
getup(y,x,dep+1,nw+val[y]-e[p].d, mn+val[y]-e[p].d);
}
void getdw(int x,int fa,int dep,int nw,int mn){
mn=min(mn,nw);
a[dep]=min(a[dep],-min(mn,0));
int p,y;
for(p=g[x];p;p=e[p].next)
if(!vis[y=e[p].y]&&y!=fa)
getdw(y,x,dep+1,nw+val[x]-e[p].d, mn);
}
void calc(int x){
int i,j,p,y,d;
getsz(x,0);
tq=0;
for(p=g[x];p;p=e[p].next)
if(!vis[y=e[p].y]) que[++tq]=node(e[p].y,e[p].d);
for(i=1;i<=sz[x]+1;i++) a[i]=INF;
a[1]=0;
for(i=1;i<=tq;i++){
y=que[i].y; d=que[i].d;
getup(y,0,1,val[y]-d,val[y]-d);
getdw(y,0,2,val[x]-d,INF);
for(j=sz[y]+1;j>0;j--) a[j]=min(a[j],a[j+1]);
}
for(i=1;i<=sz[x]+1;i++) a[i]=INF;
a[1]=0;
for(i=tq;i>=1;i--){
y=que[i].y; d=que[i].d;
getup(y,0,1,val[y]-d,val[y]-d);
getdw(y,0,2,val[x]-d,INF);
for(j=sz[y]+1;j>0;j--) a[j]=min(a[j],a[j+1]);
}
}
void work(int fr){
getsz(fr,0);
mi=size=sz[fr];
getrt(fr,0);
int x=rt,p,y;
vis[x]=1;
calc(x);
for(p=g[x];p;p=e[p].next)
if(!vis[y=e[p].y]){
work(y);
}
}
int main(){
int i,x,y,z;
n=rd();
for(i=1;i<=n;i++) val[i]=rd();
for(i=1;i<n;i++){
x=rd(),y=rd(),z=rd();
addedge(x,y,z);
addedge(y,x,z);
}
work(1);
printf("%d\n",ans);
return 0;
}
xsy 1790 - 不回头的旅行的更多相关文章
- BZOJ 3531: [Sdoi2014]旅行 [树链剖分]
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1685 Solved: 751[Submit][Status] ...
- vijos P1780 【NOIP2012】 开车旅行
描述 小\(A\)和小\(B\)决定利用假期外出旅行,他们将想去的城市从\(1\)到\(N\)编号,且编号较小的城市在编号较大的城市的西边,已知各个城市的海拔高度互不相同,记城市\(i\)的海拔高度为 ...
- Unable to load R3 module D:\Program Files\Oracle\VirtualBox/VBoxDD.DLL (VBoxDD): GetLastError=1790 (VERR_UNRESOLVED_ERROR).
Unable to load R3 module D:\Program Files\Oracle\VirtualBox/VBoxDD.DLL (VBoxDD): GetLastError=1790 ( ...
- 【BZOJ-1570】BlueMary的旅行 分层建图 + 最大流
1570: [JSOI2008]Blue Mary的旅行 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 388 Solved: 212[Submit ...
- codevs 1036 商务旅行(Targin求LCA)
传送门 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任意 ...
- nyoj 71 独木舟上的旅行(贪心专题)
独木舟上的旅行 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 进行一次独木舟的旅行活动,独木舟可以在港口租到,并且之间没有区别.一条独木舟最多只能乘坐两个人,且乘客 ...
- 【bzoj3531】 [SDOI2014]旅行
题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰.为了方便,我们 ...
- tomcat源码分析(三)一次http请求的旅行-从Socket说起
p { margin-bottom: 0.25cm; line-height: 120% } tomcat源码分析(三)一次http请求的旅行 在http请求旅行之前,我们先来准备下我们所需要的工具. ...
- 11.14 T2 小x的旅行(小x的旅行)
1.小x的旅行 (travel.pas/c/cpp) [问题描述] 小x大学毕业后,进入了某个公司做了高层管理,他每年的任务就是检查这个公司在全国各地N个分公司的各种状况,每个公司都要检查一遍,且 ...
随机推荐
- JavaScript数组之傻傻分不清系列(split,splice,slice)
因业务场景需求,需要将一个数组截断而不需要影响原数组.这里来理解一下 slice,splice,split slice() 从某个已有的数组返回选定的元素.(JavaScript Array 对象) ...
- JS数据结构及算法(二) 队列
队列是遵循先进先出的一种数据结构,在尾部添加新元素,并从顶部移除元素. 1.普通队列 function Queue() { this.items = []; } Queue.prototype = { ...
- 第二课:PHP 安装
PHP 安装 您需要做什么? 为了开始使用 PHP,您可以: 找一个支持 PHP 和 MySQL 的 Web 主机 在您自己的 PC 机上安装 Web 服务器,然后安装 PHP 和 MySQL 使用支 ...
- 【mysql】mysql has gone away
原文 http://www.jb51.net/article/23781.htm MySQL server has gone away 问题的解决方法 投稿:mdxy-dxy 字体:[增加 减小] 类 ...
- nRF52-PCA10040——Overview
Overview Zephyr applications use the nrf52_pca10040 board configuration to run on the nRF52 Developm ...
- TypeError: cannot use a string pattern on a bytes-like object
一劳永逸解决:TypeError: cannot use a string pattern on a bytes-like object TypeError: cannot use a string ...
- [文章备份]Powershell Studio 2019 5.6.160 X64破解版 Crack
- EXCEL宏做数据拆分
用处:将大容量的EXCEL工作簿分解成若干个小的工作簿 Sub aa() For i = 1 To 8 Set nb = Workbooks.Add nb.SaveAs Filename:=ThisW ...
- 如何安装mongodb.msi
到MongoDB官网下载MongoDB软件:mongodb-win32-x86_64-2008plus-ssl-3.0.2-signed.msi, 放在想要安装的地方: 如:d:\MongoDB\ 2 ...
- Mark Down 简单标记语言
MarkDown介绍=============== ## 1.标题分级介绍 #一级标题###三级标题######六级标题 一级标题============== 二级标题---------------- ...