题目:https://www.luogu.org/problemnew/show/AT2112

对于这种找路径的就直接上点分治就好。

分治时,算出每一个点到分治重心的后能剩多少油,从分治重心走到每个点最少需要多少起始油量。

对这两个数组排序后合并即可。

注意,合并的时候要保证不属于同一棵子树,这个可以利用boruvka时用到的那个技巧来实现。

#include<bits/stdc++.h>
#define N 220000
#define db double
#define ll long long
#define ldb long double
using namespace std;
inline ll read()
{
char ch=0;
ll x=0,flag=1;
while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*flag;
}
const ll inf=1e9;
struct edge{ll to,nxt,w;}e[N*2];
ll num,head[N];
inline void add(ll x,ll y,ll z){e[++num]=(edge){y,head[x],z};head[x]=num;}
bool vis[N];
ll rt,ans,size,cnt1,cnt2,w[N],sz[N],bal[N];
struct node{ll x,w,k;}f[N],g[N];
bool cmp(node a,node b){return a.x<b.x;}
bool operator<(node a,node b){return a.w<b.w;}
void get_rt(ll x,ll fa)
{
sz[x]=1;bal[x]=0;
for(ll i=head[x];i!=-1;i=e[i].nxt)
{
ll to=e[i].to;
if(vis[to]||to==fa)continue;
get_rt(to,x);sz[x]+=sz[to];
bal[x]=max(bal[x],sz[to]);
}
bal[x]=max(bal[x],size-sz[x]);
if(bal[rt]>bal[x])rt=x;
}
void get_sz(ll x,ll fa)
{
sz[x]=1;
for(ll i=head[x];i!=-1;i=e[i].nxt)
{
ll to=e[i].to;
if(vis[to]||to==fa)continue;
get_sz(to,x);sz[x]+=sz[to];
}
}
void cal1(ll x,ll k,ll t,ll fa,ll dep,ll flag)
{
if(fa==rt)flag=x;
if(w[x]>=k)f[++cnt1]=(node){t+w[x],dep,flag};
for(ll i=head[x];i!=-1;i=e[i].nxt)
{
ll to=e[i].to,v=e[i].w;
if(vis[to]||to==fa)continue;
cal1(to,max(v,k+v-w[x]),t-v+w[x],x,dep+1,flag);
}
}
void cal2(ll x,ll k,ll t,ll fa,ll dep,ll flag)
{
if(fa==rt)flag=x;
g[++cnt2]=(node){k,dep,flag};
for(ll i=head[x];i!=-1;i=e[i].nxt)
{
ll to=e[i].to,v=e[i].w;
if(vis[to]||to==fa)continue;
cal2(to,max(k,v-t),t-v+w[to],x,dep+1,flag);
}
}
void solve(ll x)
{
bal[rt=0]=inf;get_rt(x,x);get_sz(rt,rt);vis[rt]=true;
cnt1=0;cal1(rt,0,0,rt,1,rt);sort(f+1,f+cnt1+1,cmp);
cnt2=0;cal2(rt,0,0,rt,0,rt);sort(g+1,g+cnt2+1,cmp);
node a={0,-inf,0},b={0,-inf,0};
for(ll i=1,j=0;i<=cnt1;i++)
{
while(j!=cnt2&&g[j+1].x<=f[i].x)
{
j++;
if(g[j].k==a.k)a=max(a,g[j]);
else
{
b=max(b,g[j]);
if(a<b)swap(a,b);
}
}
if(f[i].k!=a.k)ans=max(ans,f[i].w+a.w);
else ans=max(ans,f[i].w+b.w);
}
for(ll i=head[rt];i!=-1;i=e[i].nxt)
{
ll to=e[i].to;
if(vis[to])continue;
size=sz[to];solve(to);
}
}
int main()
{
ll n=read();
for(ll i=1;i<=n;i++)w[i]=read();
num=-1;memset(head,-1,sizeof(head));
for(ll i=1;i<n;i++)
{
ll x=read(),y=read(),z=read();
add(x,y,z);add(y,x,z);
}
ans=1;size=n;solve(1);printf("%lld\n",ans);
return 0;
}

AT2112 Non-redundant Drive的更多相关文章

  1. AHCI: Failed to attach drive to Port1 (VERR_GENERAL_FAILURE).

    在mac操作系统下,安装VirtualBoxVm虚拟机,虚拟机里面安装wind7操作系统.在启动虚拟机的时候报错:AHCI: Failed to attach drive to Port1 (VERR ...

  2. Windows Azure Storage (17) Azure Storage读取访问地域冗余(Read Access – Geo Redundant Storage, RA-GRS)

    <Windows Azure Platform 系列文章目录> 细心的用户会发现,微软在国外和国内的数据中心建设都是成对的,比如香港数据中心(Asia East)和新加坡的数据中心(Sou ...

  3. vmware安装win7提示No CD-ROM drive to use:GCDROM not loaded

    今天安装win7 64位的操作系统到vmware虚拟机,以为一切事如此的简单,因为自己以前经常拿vmware来装系统,结果确出现下面莫名其妙的错误: 提示说没有CD-ROM,可是我明明在vmware的 ...

  4. Ignite 配置更新Oracle JDBC Drive

           如果使用Oracle 12C 作为Ignite 的Repository的话,在Repository Createion Wizard的配置过程中,会出现ORA-28040:No matc ...

  5. 网盘的选择,百度网盘、google drive 还是 Dropbox

    我是国内用户,需要越过Chinawall 我使用的是一枝红杏,用着还行 如果要买,结账时输入'laod80' 一枝红杏官网:官网地址 Dropbox: 稳定,速度快 Dropbox官网:链接 操作十分 ...

  6. POJ 3177 Redundant Paths(边双连通的构造)

    Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13717   Accepted: 5824 ...

  7. UEFI Bootable USB Flash Drive - Create in Windows(WIN7 WIN8)

    How to Create a Bootable UEFI USB Flash Drive for Installing Windows 7, Windows 8, or Windows 8.1 In ...

  8. Create a SQL Server Database on a network shared drive

    (原文地址:http://blogs.msdn.com/b/varund/archive/2010/09/02/create-a-sql-server-database-on-a-network-sh ...

  9. 【转】Expire Google Drive Files 让Google Docs云盘共享连接在指定时间后自动失效

    最近在清理Google Docs中之前共享过的文件链接,发现Google Docs多人协作共享过的链接会一直存在,在实际操作中较不灵活.正好订阅的RSS推送了Pseric写的这篇文章 - Expire ...

随机推荐

  1. CICD 基础

    代码测试覆盖率 最近在负责相关插件的集成,今天第一次接触到"代码覆盖率"这个概念,那么,就做些简单的笔记吧. 好文 如何提高一个研发团队的"代码速度"? 代碼覆 ...

  2. HDU 4366 Successor(dfs序 + 分块)题解

    题意:每个人都有一个上司,每个人都有能力值和忠诚值,0是老板,现在给出m个询问,每次询问给出一个x,要求你找到x的所有直系和非直系下属中能力比他高的最忠诚的人是谁 思路:因为树上查询很麻烦,所以我们直 ...

  3. hdu5628 Clarke and math

    题目地址 题目链接 题意 求 \[ g(i)=\sum_{i1|i}\sum_{i_2|i_1}\sum_{i_3|i_2}...\sum_{i_k|i_{k-1}}f(i_k)\space mod\ ...

  4. C# 里调用vb的inputbox弹出窗

    https://blog.csdn.net/hutao1101175783/article/details/16800871 先对项目添加对Microsoft.VisualBasic的引用 Inter ...

  5. HDU 3333 Turing Tree(树状数组/主席树)

    题意 给定一个长度为 \(n​\) 的序列,\(m​\) 个查询,每次查询区间 \([L,R]​\) 范围内不同元素的和. \(1\leq T \leq 10\) \(1 \leq n\leq 300 ...

  6. 【C#】委托的发展

    "用事件去处理程序, 进而解决问题" ---- 委托的目的 委托早在C#2的时候就已经初具模型, 但是并不是特别灵活, 制止C#3才在代码中被广泛使用. C#4中泛型委托, C#5 ...

  7. Docker与.Net项目类型

    使用Docker的项目,要求:基础类库与平台无关=>.netCore项目..netStandard项目 公共项目:.netCore项目 入口项目:.netStandard项目 例如:webapi ...

  8. 常见的Java面试题及答案整理

    1. 基础篇 1. 面向对象特征:封装,继承,多态和抽象 封装封装给对象提供了隐藏内部特性和行为的能力.对象提供一些能被其他对象访问的方法来改变它内部的数据.在 Java 当中,有 3 种修饰符: p ...

  9. 从DFS到记忆化DFS到动态规划

    什么是动态规划? 动态规划(Dynamic Programming)是通过组合子问题的解来解决问题的.动态规划是用于求解包含重叠子问题的最优化问题的方法.其基本思想是,将原问题分解为相似的子问题.在求 ...

  10. N的阶乘(10000) 51 nod——1057 (大数)

    像这些大整数加法或者乘法什么的思想都一样,就是截位存取,累积进位,最后逆序输出就可以啦 PS:小生是用10000来存取的,300MS就能A,如果单个存取有点危险,题目时间限制好像是1000ms,大家可 ...