传送门

考虑树上乱搞

首先这是满足二分性质的,如果在某个时间可以完成工作那么比他更长的时间肯定也能完成工作

然后考虑二分,设当前答案为$mid$,如果有一条链的长度大于$mid$,那么这条链上必须得删去一条边。我们可以贪心的删去所有可以删去的边中最长的,然后看看最长边减去删去的边是否小于等于$mid$,如果成立说明可行

然后考虑怎么solve,我们可以用树上差分,就是对于每个点把它看做他父亲到他的边,每个点记录一个$s$,然后对于一条链,两个端点++,lca-=2。如果有一个点的$s$等于大于$mid$的链的条数,说明它被所有的链给覆盖,然后求一个最大值就好了

然后每一条链的lca都要求出来……实际上直接每一条都$O(logn)$求出来也没关系……不过代码里用的是tarjan离线求的,所以复杂度是$O(n+m)$

总复杂度是$O(nlogn)$(复杂度并没有降……直接树剖求LCA可能更省力啊……)

 //minamoto
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,:;}
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=3e5+;
int head[N],Next[N<<],ver[N<<],edge[N<<],tot;
int hq[N<<],nq[N<<],vq[N<<],tq;
int dis[N],a[N],fa[N],s[N],vis[N];
int n,mx,ans,res,num,m;
struct node{
int u,v,len,lca;
node(){}
node(int u,int v,int len,int lca):u(u),v(v),len(len),lca(lca){}
inline void solve(){++s[u],++s[v],s[lca]-=;}
}q[N];
inline void add(int u,int v,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
}
inline void addq(int u,int v){
vq[++tq]=v,nq[tq]=hq[u],hq[u]=tq;
}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void dfs(int u,int fa){
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa){
dfs(v,u),s[u]+=s[v];
}
}
if(s[u]==num) cmax(res,a[u]);
}
bool check(int x){
memset(s,,sizeof(s));
num=res=;
for(int i=;i<=m;++i)
if(q[i].len>x){
q[i].solve(),++num;
}
dfs(,);
return mx-res<=x;
}
void tarjan(int u,int ff){
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v==ff) continue;
dis[v]=dis[u]+edge[i];
tarjan(v,u);
a[v]=edge[i];
int f1=find(v),f2=find(u);
if(f1!=f2) fa[f1]=f2;
vis[v]=;
}
for(int i=hq[u];i;i=nq[i]){
int v=vq[i];
if(vis[v]){
int p=(i+)>>,LCA=find(v);
q[p]=node(u,v,dis[u]+dis[v]-*dis[LCA],LCA);
cmax(mx,q[p].len);
}
}
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),m=read();
for(int i=,u,v,e;i<n;++i)
u=read(),v=read(),e=read(),add(u,v,e),add(v,u,e);
for(int i=;i<=n;++i) fa[i]=i;
for(int i=,u,v;i<=m;++i)
u=read(),v=read(),addq(u,v),addq(v,u);
tarjan(,);
int l=,r=mx,mid;
while(l<=r){
mid=(l+r)>>;
if(check(mid)) r=mid-,ans=mid;
else l=mid+;
}
printf("%d\n",ans);
return ;
}

洛谷P2680 运输计划(树上差分+二分)的更多相关文章

  1. 洛谷P2680 运输计划——树上差分

    题目:https://www.luogu.org/problemnew/show/P2680 久违地1A了好高兴啊! 首先,要最大值最小,很容易想到二分: 判断当前的 mid 是否可行,需要看看有没有 ...

  2. 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)

    P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...

  3. 洛谷 P2680 运输计划 解题报告

    P2680 运输计划 题目背景 公元2044年,人类进入了宇宙纪元. 题目描述 公元2044年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道,每条航道建立在两个星 ...

  4. 洛谷P2680 运输计划 [LCA,树上差分,二分答案]

    题目传送门 运输计划 Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n?1 条双向航道,每条航道建立在两个星球之间, 这 n?1 条航道连通了 L 国的所 ...

  5. 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)

    [题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...

  6. [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告

    [NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...

  7. 洛谷 P2680 运输计划(NOIP2015提高组)(BZOJ4326)

    题目背景 公元 \(2044\) 年,人类进入了宇宙纪元. 题目描述 公元\(2044\) 年,人类进入了宇宙纪元. L 国有 \(n\) 个星球,还有 \(n-1\) 条双向航道,每条航道建立在两个 ...

  8. 洛谷——P2680 运输计划

    https://www.luogu.org/problem/show?pid=2680 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每 ...

  9. [NOIP2015] 提高组 洛谷P2680 运输计划

    题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...

随机推荐

  1. Git如何强制拉取一个远程分支到本地分支(转载)

    有时候,我们在使用git pull指令想把一个远程分支拉取到本地分支的时候,老是会拉取失败,这一般是因为某种原因,本地分支和远程分支的内容差异无法被git成功识别出来,所以git pull指令什么都不 ...

  2. ZOJ - 3430 Detect the Virus —— AC自动机、解码

    题目链接:https://vjudge.net/problem/ZOJ-3430 Detect the Virus Time Limit: 2 Seconds      Memory Limit: 6 ...

  3. 虚拟化网络之OpenvSwitch

    OpenvSwitch简称OVS,官网(http://openvswitch.org/) OVS是一个高质量.多层的虚拟交换软件,即虚拟交换机. OpenvSwitch的见的相关组件: ovs-vsw ...

  4. 我的.emacs文件,用于C/C++及shell编程。

    1. [代码]我的.emacs文件,用于C/C++及shell编程.;;我的配置;;1.基本配置;;外观配置***************;;禁用启动画面(setq inhibit-startup-m ...

  5. BZOJ 1208 [HNOI2004]宠物收养所:Splay(伸展树)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1208 题意: 有一个宠物收养所,在接下来一段时间内会陆续有一些宠物进到店里,或是一些人来领 ...

  6. Es6 学习笔记(一)数组扩展

    扩展运算符 ... 1.数组的扩展运算符将一个数组转换成一个逗号分隔的参数序列 console.log(...[1,2,3])   //1,2,3 ['a', 'b',...[1,3]]   //a, ...

  7. ResNeXt——与 ResNet 相比,相同的参数个数,结果更好:一个 101 层的 ResNeXt 网络,和 200 层的 ResNet 准确度差不多,但是计算量只有后者的一半

    from:https://blog.csdn.net/xuanwu_yan/article/details/53455260 背景 论文地址:Aggregated Residual Transform ...

  8. linux网络编程 ntohs, ntohl, htons,htonl inet_aton等详解

    ntohs =net to host short int 16位 htons=host to net short int 16位 ntohs =net to host long int 32位 hto ...

  9. MFC默认窗口类名称

    // special AFX window class name mangling #ifndef _UNICODE #define _UNICODE_SUFFIX #else #define _UN ...

  10. 模拟jQuery的一些功能

    //getStyle function getStyle(obj,attr){ if(obj.currentStyle){ return obj.currentStyle[attr]; } else{ ...