洛谷P2680 运输计划(树上差分+二分)
考虑树上乱搞
首先这是满足二分性质的,如果在某个时间可以完成工作那么比他更长的时间肯定也能完成工作
然后考虑二分,设当前答案为$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 运输计划(树上差分+二分)的更多相关文章
- 洛谷P2680 运输计划——树上差分
题目:https://www.luogu.org/problemnew/show/P2680 久违地1A了好高兴啊! 首先,要最大值最小,很容易想到二分: 判断当前的 mid 是否可行,需要看看有没有 ...
- 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)
P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...
- 洛谷 P2680 运输计划 解题报告
P2680 运输计划 题目背景 公元2044年,人类进入了宇宙纪元. 题目描述 公元2044年,人类进入了宇宙纪元. \(L\)国有\(n\)个星球,还有\(n-1\)条双向航道,每条航道建立在两个星 ...
- 洛谷P2680 运输计划 [LCA,树上差分,二分答案]
题目传送门 运输计划 Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n?1 条双向航道,每条航道建立在两个星球之间, 这 n?1 条航道连通了 L 国的所 ...
- 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)
[题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...
- [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告
[NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...
- 洛谷 P2680 运输计划(NOIP2015提高组)(BZOJ4326)
题目背景 公元 \(2044\) 年,人类进入了宇宙纪元. 题目描述 公元\(2044\) 年,人类进入了宇宙纪元. L 国有 \(n\) 个星球,还有 \(n-1\) 条双向航道,每条航道建立在两个 ...
- 洛谷——P2680 运输计划
https://www.luogu.org/problem/show?pid=2680 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每 ...
- [NOIP2015] 提高组 洛谷P2680 运输计划
题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球. 小 P 掌管一家 ...
随机推荐
- 微信小程序开发:学习笔记[1]——Hello World
微信小程序开发:学习笔记[1]——Hello World 快速开始 1.前往微信公众平台下载微信开发者工具. 地址:https://mp.weixin.qq.com/debug/wxadoc/dev/ ...
- css三角形实现的几种方法的区别
演变: .triangle{ height: 30px; width: 30px; display: inline-block; border: 30px solid; border-color: # ...
- CentOs7 配置nfs 系统
一.介绍 NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,功能是让客户端通过网络访问不同主机上磁盘里的数据,主要用在类Unix系统上实现文件共享 ...
- 使用pip安装第三方库报错记录
今天在使用pycharm导入第三方库的时候,报了好多超时错误,还有标题中的找不到版本,应该是网络的原因,记录下解决的办法: raise ReadTimeoutError(self._pool, Non ...
- NOIP 2016【蚯蚓】
好吧,我承认我是个智障-- 这道题一眼看上去就是个堆,然而实际上有单调性. 注意到,如果 \(q = 0\) 的话,将蚯蚓的左右两边分开丢进两个队列中,则两个队列都是单调不增的,因为每次取出的蚯蚓长度 ...
- HihoCoder1672 : 区间问题([Offer收割]编程练习赛41)(贪心)
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定N个区间[Ai, Bi],请你找到包含元素最少的整数集合S,使得每个区间都至少有两个整数在S中. 例如给定三个区间[1 ...
- 【C++】*p++ = *p不同环境下操作不同
实测,Ubuntu16.04,gcc 5.3.0&5.4.0(编译选项选择C++11和不选择新标准结果相同) #include<iostream> using namespace ...
- DataGrid当列宽超出当前宽度时,没有数据也恒有滚动条
附件是DataGrid支持滚动条的文件. 具体使用如下: 1)DataGrid使用控件模板 <Setter Property="Template" Value="{ ...
- MSTAR 平台
MApp_Menu.c ZUI_exefunc.h //菜单属性 MApp_ZUI_APItables.h #define GETWNDINFO(hwnd) (&g_GUI_WindowLis ...
- ceph应用情况分析
1.概述 ceph是分布式的开源存储系统,同时支持块存储.对象存储和文件系统,ceph可以满足高性能.高可靠性和高扩展等特性. 目前ceph作为开源分布式存储已经被大量使用,尤其是在云环境下的应用,下 ...