传送门

考虑树上乱搞

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

然后考虑二分,设当前答案为$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. Other Linker flags 添加 -Objc导致包冲突

    Other Linker flags 添加 -Objc导致包冲突 先尝试不添加-Objc,不行的话尝试下面的方法. 第三方冲突解决办法: https://www.jianshu.com/p/02846 ...

  2. mysql 创建用户与授权

    权限管理 我们都知道,最高权限管理者是 root 用户 , 它拥有着最高的权限操作,包括 : select(查询) ,update(修改) , delete(删除,有事没事都不要用这个,反正也不能给这 ...

  3. Database: key

    super-key: Any key that has more columns than necessary to uniquely identify each row in the table i ...

  4. ios浮层滑动不流畅解决方案

    前段时间做了一个浮层,但在ios上,浮层滑动不流畅,基本上是随着手指的移动而移动,经研究加上-webkit-overflow-scrolling: touch即可 eg: <!DOCTYPE h ...

  5. mini2440移植uboot 2011.03(下)

    参考博文: <u-boot-2011.03在mini2440/micro2440上的移植> 移植(五)添加nand支持: host@debian:~/soft/mini2440/u-boo ...

  6. swoole+nginx反向代理

    nginx配置: server { listen 80; server_name www.swoole.com; root /data/wwwroot/www.swoole.com; location ...

  7. hdu 6103(Kirinriki)

    题目链接:Kirinriki 题目描述: 找两个不重叠的字符串A,B. 使得dis(A,B)<=m;\(dis(A,B)= \sum _{i=0}^{n-1} \left | A_i-B_{n- ...

  8. Python 实现「食行生鲜」签到领积分

    用过食行生鲜的同学应该知道,每天可以在食行生鲜签到,签到可以领到 20 积分,在购物时可以抵 2 毛钱.钱虽少,但是积少成多,买菜时可以抵扣一两块钱还是不错的. 今天我们就用 Python 来实现自动 ...

  9. 结合Django+celery二次开发定时周期任务

    需求: 前端时间由于开发新上线一大批系统,上完之后没有配套的报表系统.监控,于是乎开发.测试.产品.运营.业务部.财务等等各个部门就跟那饥渴的饿狼一样需要 各种各样的系统数据满足他们.刚开始一天一个还 ...

  10. 详解使用python crontab设置linux定时任务

    熟悉linux的朋友应该知道在linux中可以使用crontab设置定时任务.可以通过命令crontab -e编写任务.当然也可以直接写配置文件设置任务. 但是有时候希望通过脚本自动设置,比如我们应用 ...