传送门

Description

Input

Output

一个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间。

Sample Input

6 3

1 2 3

1 6 4

3 1 7

4 3 6

3 5 5

3 6

2 5

4 5

Sample Output

11

HINT

Solution

很显然第一步是求出lca然后求出每个运输计划的长度

题目要求一个时间最大值的最小值 很明显要二分

二分一个运输时间,统计所有超过这个时间的运输计划经过的路径

找出其中被所有超时计划包括的最大路径 直接判断就行

lca和长度我用的tarjan

统计每条路径的经过次数那就树上差分喽( ̄▽ ̄)/

Code

//By Menteur_Hxy
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define M(a,b) memset(a,(b),sizeof(a))
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define E(i,u) for(register int i=head[u];i;i=nxt[i])
using namespace std; int read() {
int x=0,f=1; char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-f; c=getchar();}
while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
return x*f;
} const int N=300010;
bool vis[N];
int n,m,ecnt,maxlen,res,num;
int nxt[N<<1],to[N<<1],w[N<<1],head[N],ln[N],rn[N],len[N],lca[N],dis[N],fa[N],sum[N],cnt[N];
vector <int> V[N]; int getf(int x) {return fa[x]==x?x:fa[x]=getf(fa[x]);} void tarjan(int u,int pre) {
E(i,u) { int v=to[i];
if(v==pre) continue;
dis[v]=dis[u]+w[i];
tarjan(v,u);
cnt[v]=w[i];//差分时用
}
int siz=V[u].size();
F(i,0,siz-1) {
int id=V[u][i],v=ln[id]==u?rn[id]:ln[id];
if(!vis[v]) continue;
lca[id]=getf(v);
len[id]=dis[v]+dis[u]-2*dis[lca[id]];
maxlen=max(len[id],maxlen);
}
vis[u]=1;fa[u]=pre;
} void dfs(int u,int pre) {
E(i,u) { int v=to[i];
if(v==pre) continue;
dfs(v,u);
sum[u]+=sum[v];
}
if(sum[u]==num&&cnt[u]>res) res=cnt[u];
} bool jud(int t) {
num=res=0;
M(sum,0);
F(i,1,m) if(len[i]>t) sum[ln[i]]++,sum[rn[i]]++,sum[lca[i]]-=2,num++;
if(num==0) return 1;
dfs(1,0);
return maxlen-res<=t;
} #define add(a,b,c) nxt[++ecnt]=head[a],to[ecnt]=b,head[a]=ecnt,w[ecnt]=c
#define ins(a,b,c) add(a,b,c),add(b,a,c)
int main() {
n=read(),m=read();
F(i,1,n) fa[i]=i;
F(i,1,n-1) {
int a=read(),b=read(),c=read();
ins(a,b,c);
}
F(i,1,m) {
int a=read(),b=read();
ln[i]=a,rn[i]=b;
V[a].push_back(i);
V[b].push_back(i);
}
tarjan(1,0);
// F(i,1,m) cout<<lca[i]<<" "<<len[i]<<endl;
int l=0,r=maxlen;
int ans=0x3f3f3f3f;
while(l<=r) {
int mid=(l+r)>>1;
if(jud(mid)) ans=min(ans,mid),r=mid-1;
else l=mid+1;
}
printf("%d",ans);
return 0;
}

[luogu2680] 运输计划 (lca+二分+树上差分)的更多相关文章

  1. P2680 运输计划(二分+树上差分)

    P2680 运输计划 链接 分析: 二分+树上差分. 首先可以二分一个答案,那么所有比这个答案大的路径,都需要减去些东西才可以满足这个答案. 那么减去的这条边一定在所有的路径的交集上. 那么如果求快速 ...

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

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

  3. 2018.09.26 bzoj4326: NOIP2015 运输计划(二分+树上差分)

    传送门 简单树上操作. 先转边权为点权. 显然所有的询问操作对应的路径会有一些交点,那么我们可以直接二分答案,对于所有大于二分值的询问用树上差分维护,最后dfs一遍每个点被覆盖了几次,当前情况合法当且 ...

  4. [NOIp2015]运输计划 (二分 $+$ 树上差分)

    #\(\mathcal{\color{red}{Description}}\) \(Link\) 在一棵带有边权的树上,可以选择使一条边权为零.然后对于所有\(M\)条链,使其链长最大值最小. #\( ...

  5. 【NOIP2015】运输计划(二分,差分)

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

  6. bzoj 4326: NOIP2015 运输计划【树链剖分+二分+树上差分】

    常数巨大,lg上开o2才能A 首先预处理出运输计划的长度len和lca,然后二分一个长度w,对于长度大于w的运输计划,在树上差分(d[u]+1,d[v]+1,d[lca]-2),然后dfs,找出所有覆 ...

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

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

  8. P2680 运输计划 二分+树上差分

    又咕咕了几天\(QwQ\) 思路:二分+树上差分 提交:\(\geq5\)次 错因:\(lca\)写错+卡了很久常数(哪位大佬帮我康康,有更好的写法请指出\(QwQ\)) 题解: 我们先将原问题转化为 ...

  9. [NOIP2015]运输计划 线段树or差分二分

    目录 [NOIP2015]运输计划 链接 思路1 暴力数据结构 思路2 二分树上差分 总的 代码1 代码2 [NOIP2015]运输计划 链接 luogu 好久没写博客了,水一篇波. 思路1 暴力数据 ...

随机推荐

  1. java.lang.AbstractMethodError: org.apache.xerces.dom.DocumentImpl.getXmlStandalone()Z解决办法

    2019-05-20 23:02:20.168 |-INFO  [http-nio-8001-exec-2] com.xxx.ecc.cloudbiz.service.payment.impl.Wei ...

  2. HDU 4507

    数位DP. 一般是利用DFS来求数位DP了,结合了记忆化搜索.设dp[i][j][k]为前i位,并且前i位的数位和mod7为j,前i位的数字的表示数字值mod7.为什么可以这样呢?因为继续DFS下去, ...

  3. Marching squares &amp; Marching cubes

    提要 Marching squares 主要是用于从一个地图(用二维数组表示)生成轮廓的算法.Marching cubes则相应的是在空间生成网格的方法.最常见的应用就是天气预报中气压图的生成.还经常 ...

  4. DRP——重定向与转发

    重定向 重定向就是又一次进行请求.第一次请求.容器推断请求的类型,是否须要重定向. 重定向的语句是"response.SendRedirect("index.jsp"); ...

  5. DecimalFormat格式化输出带小数的数字类型

    刚開始 double d = 333333333.333333333; System.out.println(d); 输出结果为3.333333333333333E8 网上找到了DecimalForm ...

  6. POJ1742 Coins 背包

    题目大意:给出一些钱币的价值和对应的数目,求在一定价值限定下这些钱币能凑成的价值数. 本题用多重背包直接拆分或二进制拆分法都太慢.说起处理一组物品,完全背包可算是比较效率高的,但是本题中物体的数目是有 ...

  7. HTML5动态时钟

    实现效果 源码可以去github下载 地址:https://github.com/feifeiliu/jsBlock 参考:慕课网动态时钟

  8. 快速排序c++实现 快排C++代码实现

    快速排序c++实现 快排C++ 第一.算法描述 快速排序由C. A. R. Hoare在1962年提出,该算法是目前实践中使用最频繁,实用高效的最好排序算法, 快速排序算法是采用分治思想的算法,算法分 ...

  9. flash as3.0学习笔记

    F9开动作模板 trace输出 trace(a); 影片剪辑 var mc:MovieClip = new MovieClip();//属性(x,y轴)方法 play,stop mc.x = 10 / ...

  10. jTemplates的教程,包括{#if}{#foreach}{#for}的简单使用

    最近在做一些局部刷新的分页工作,一般不使用既成的插件的话,就是在脚本里面重新渲染一个局部的html,把需要局部分页的模块重写一遍,还需要在控制器里再定义一个方法返回所需的局部数据,这种做法相当冗余,所 ...