题目传送门

运输计划

Description

公元 2044 年,人类进入了宇宙纪元。L 国有 n 个星球,还有 n?1 条双向航道,每条航道建立在两个星球之间,
这 n?1 条航道连通了 L 国的所有星球。小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如
:有一艘物流飞船需要从 ui 号星球沿最快的宇航路径飞行到 vi 号星球去。显然,飞船驶过一条航道是需要时间
的,对于航道 j,任意飞船驶过它所花费的时间为 tj,并且任意两艘飞船之间不会产生任何干扰。为了鼓励科技
创新, L 国国王同意小 P 的物流公司参与 L 国的航道建设,即允许小P 把某一条航道改造成虫洞,飞船驶过虫
洞不消耗时间。在虫洞的建设完成前小 P 的物流公司就预接了 m 个运输计划。在虫洞建设完成后,这 m 个运输
计划会同时开始,所有飞船一起出发。当这 m 个运输计划都完成时,小 P 的物流公司的阶段性工作就完成了。如
果小 P 可以自由选择将哪一条航道改造成虫洞, 试求出小 P 的物流公司完成阶段性工作所需要的最短时间是多
少?
 

Input

第一行包括两个正整数 n,m,表示 L 国中星球的数量及小 P 公司预接的运输计划的数量,星球从 1 到 n 编号。
接下来 n-1 行描述航道的建设情况,其中第 i 行包含三个整数 ai,bi 和 ti,
表示第 i 条双向航道修建在 ai 与 bi 两个星球之间,任意飞船驶过它所花费的时间为 ti。
接下来 m 行描述运输计划的情况,其中第 j 行包含两个正整数 uj 和 vj,表示第 j 个运输计划是从 uj 号星球飞往 vj号星球。
数据保证 1≤ui,vi≤n ,n,m<=300000
数据保证 1≤ai,bi≤n 且 0≤ti≤1000。
 

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
将第 1 条航道改造成虫洞: 则三个计划耗时分别为:11,12,11,故需要花费的时间为 12。
将第 2 条航道改造成虫洞: 则三个计划耗时分别为:7,15,11,故需要花费的时间为 15。
将第 3 条航道改造成虫洞: 则三个计划耗时分别为:4,8,11,故需要花费的时间为 11。
将第 4 条航道改造成虫洞: 则三个计划耗时分别为:11,15,5,故需要花费的时间为 15。
将第 5 条航道改造成虫洞: 则三个计划耗时分别为:11,10,6,故需要花费的时间为 11。
故将第 3 条或第 5 条航道改造成虫洞均可使得完成阶段性工作的耗时最短,需要花费的时间为 11。


  分析:

  一道$LCA$+二分的码农题。

  不难看出,一定是需要求$LCA$来求两点的路径的。但是我们怎么处理减去一条边呢?

  如果是暴力枚举每一条边,复杂度是$O(nm\log (n))$的,不过也能拿$60$分了。

  考虑优化,题目要求的东西其实就是最长航线的最短时间,那么显然是二分答案。我们二分航线所需的最长时间,然后我们统计哪些航线的时间大于当前的$mid$值,然后$O(n)$搜索找出被所有大于$mid$的航线经过的边的最大值,然后用最长航线时间减去这个最大值,如果仍大于$mid$则不合法,否则就可以更行答案然后继续。

  这里博主用的是倍增求$LCA$,另外这题数据较大,二分的时候需要控制边界,把二分的范围缩小一些。

  Code:

//It is made by HolseLee on 21st Sep 2018
//Noip2015 D2T3
#include<cstdio>
#include<algorithm>
#define N 300020
#define Max(a,b) (a)>(b)?(a):(b)
using namespace std; int head[N],dep[N],sum[N],f[N][],ch[N],u[N],v[N],lca[N],dg[N],len[N];
int n,m,cnte,ans,root,maxx,cnt,maxe,maxdis;
struct Edge {
int to,val,nxt;
Edge() {}
Edge(const int &_x,const int &_y,const int &_z): to(_x),val(_y),nxt(_z) {}
}e[N<<]; inline int read()
{
char ch=getchar(); int num=;
while( ch<'' || ch>'' ) ch=getchar();
while( ch>='' && ch<='' ) {
num=(num<<)+(num<<)+(ch^); ch=getchar();
}
return num;
} void print(int x)
{
if( x> ) print(x/);
putchar(x%+'');
} inline void add(int x,int y,int z)
{
e[++cnte]=Edge(y,z,head[x]);
head[x]=cnte;
} void ready(int x,int fa)
{
dep[x]=dep[fa]+; f[x][]=fa;
for(int i=head[x]; i; i=e[i].nxt) {
int y=e[i].to;
if( y==fa ) continue;
sum[y]=sum[x]+e[i].val;
ready(y,x);
}
} void init()
{
for(int j=; j<=; ++j)
for(int i=; i<=n; ++i)
f[i][j]=f[f[i][j-]][j-];
} inline int LCA(int x,int y)
{
if( dep[x]<dep[y] ) x^=y^=x^=y;
for(int i=; i>=; --i)
if( f[x][i]==y ) return y;
else if( dep[f[x][i]]>=dep[y] ) x=f[x][i];
if( x==y ) return x;
for(int i=; i>=; --i)
if( f[x][i]!=f[y][i] ) x=f[x][i],y=f[y][i];
return f[x][];
} void dfs(int x)
{
for(int i=head[x]; i; i=e[i].nxt) {
int y=e[i].to;
if( y==f[x][] ) continue;
dfs(y);
ch[x]+=ch[y];
}
if( ch[x]==cnt && maxx<(sum[x]-sum[f[x][]]) )
maxx=sum[x]-sum[f[x][]];
} inline bool check(int x)
{
for(int i=; i<=n; ++i)ch[i]=;
cnt=; maxx=;
for(int i=; i<=m; ++i)
if( len[i]>x ) {
ch[u[i]]++, ch[v[i]]++;
ch[lca[i]]-=; cnt++;
}
dfs(root);
if( maxdis-maxx>x ) return false;
return true;
} int main()
{
n=read(), m=read();
int x,y,z;
for(int i=; i<n; ++i) {
x=read(), y=read(), z=read();
add(x,y,z), add(y,x,z);
dg[x]++, dg[y]++;
if( dg[x]>dg[root] ) root=x;
if( dg[y]>dg[root] ) root=y;
maxe=Max(maxe,z);
}
ready(root,); init();
for(int i=; i<=m; ++i) {
x=read(), y=read();
u[i]=x, v[i]=y, lca[i]=LCA(x,y);
len[i]=sum[x]+sum[y]-(sum[lca[i]]<<);
maxdis=Max(maxdis,len[i]);
}
int l=maxdis-maxe, r=maxdis, mid;
while( l<=r ) {
mid=(l+r)>>;
if( check(mid) ) r=mid-, ans=mid;
else l=mid+;
}
print(ans);
return ;
}

洛谷P2680 运输计划 [LCA,树上差分,二分答案]的更多相关文章

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

    传送门 考虑树上乱搞 首先这是满足二分性质的,如果在某个时间可以完成工作那么比他更长的时间肯定也能完成工作 然后考虑二分,设当前答案为$mid$,如果有一条链的长度大于$mid$,那么这条链上必须得删 ...

  2. 【Luogu】P2680运输计划(树上差分+二分)

    题目链接 总体思路……怎么说呢……是个暴力吧…… 首先用倍增预处理出每条路径的长度. 然后按长度把路径排序. 然后二分答案.对于当前答案mid检验,怎么检验呢? 首先差分把所有长度比mid大的链上除了 ...

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

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

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

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

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

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

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

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

  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. 原生JS实现点击一个按钮显示一个div,再点击按钮div隐藏,或点击除div外其它空白处div隐藏

    <!DOCTYPE html> <html style="font-size: 24px"> <head> <title>js点击按 ...

  2. C++设计实现算法时易犯错误

    1.未初始化 指针未初始化为NULL,造成判断条件出错 数值未初始化为0,造成数组超界,内存泄漏 2. long long输入时 lld or I64d 写成d一定出错 3.gcc编译报错:程序中有游 ...

  3. vijos 1243 生产产品 DP + 单调队列优化

    LINK 题意:有1个产品,m个步骤编号为1~m.步骤要在n个机器人的手中生产完成.其中,第i个步骤在第j个机器人手中的生产时间给定为$T[i][j]$,切换机器人消耗cost.步骤必须按顺序,同一个 ...

  4. Python学习笔记(补充)Split 用法

    >>> u = "www.doiido.com.cn" #使用默认分隔符 >>> print u.split() ['www.doiido.co ...

  5. 重构改善既有代码设计--重构手法14:Hide Delegate (隐藏委托关系)

    客户通过一个委托类来调用另一个对象.在服务类上建立客户所需的所有函数,用以隐藏委托关系. 动机:封装即使不是对象的最关机特性,也是最关机特性之一.“封装”意味着每个对象都应该少了解系统的其他部分.如此 ...

  6. [php]referer应用--http防盗链技术

    1.防盗链的理解 所谓防盗链是防止其他的网站引用自己网站的资源连接,比如图片.视频等等,但是并不会阻碍从自己网站上享受资源的用户,这就要求能够将其他网站的连接请求阻止 2.防盗链的原理 其实从自己网站 ...

  7. 下载Google My Tracks

    http://code.google.com/p/mytracks/source/browse/?name=2.0.2#hg%2FMyTracks%253Fstate%253Dclosed 需要类似的 ...

  8. POJ 3734 Blocks (矩阵快速幂)

    题目链接 Description Panda has received an assignment of painting a line of blocks. Since Panda is such ...

  9. 安装Docker-ce

    Docker Engine改为Docker CE(社区版) 它包含了CLI客户端.后台进程/服务以及API.用户像以前以同样的方式获取.Docker Data Center改为Docker EE(企业 ...

  10. Java错误提示:Syntax error, insert "}" to complete Block

    从网上复制了一段java代码到Eclipse里面,调整了一下格式,把Eclipse提示的明显有问题的地方,主要是空格,删掉了,但还是在最后一个分号那里提示“Syntax error, insert & ...