[NOIP2015]运输计划 D2 T3

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号星球。

Output

共1行,包含1个整数,表示小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

【样例说明】 
将第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和所用时间,然后二分答案。找出所有用时比mid大的路径,那么如果我们将边 i 变成虫洞,就要保证所有用时超过mid的路径都经过 i ,并且在 i 变成虫洞后,这些路径的长度都小于mid。所以用差分数组处理一下每条边有多少条这样的路径经过就行了。

为了降低常数,本人代码里还做了几处小优化,可能会发挥用处

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
const int maxn=300010;
int n,m,cnt,maxx,minn;
int head[maxn],to[maxn<<1],next[maxn<<1],val[maxn<<1];
int deep[maxn],son[maxn],top[maxn],fa[maxn],size[maxn],dis[maxn],v[maxn];
int s[maxn],q[maxn],p1[maxn],p2[maxn],pa[maxn],len[maxn];
int readin() //读入优化
{
int ret=0; char gc;
while(gc<'0'||gc>'9') gc=getchar();
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret;
}
void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
void dfs1(int x)
{
size[x]=1,q[++q[0]]=x;
for(int i=head[x];i!=-1;i=next[i])
{
if(to[i]!=fa[x])
{
v[to[i]]=val[i],deep[to[i]]=deep[x]+1,dis[to[i]]=dis[x]+val[i],fa[to[i]]=x;
dfs1(to[i]);
size[x]+=size[to[i]];
if(size[to[i]]>size[son[x]]) son[x]=to[i];
}
}
}
int getlca(int x,int y) //树剖
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);
x=fa[top[x]];
}
if(deep[x]>deep[y]) swap(x,y);
return x;
}
int check(int sta)
{
int i,sum=0;
memset(s,0,sizeof(s));
for(i=1;i<=m;i++)
if(len[i]>sta)
s[p1[i]]++,s[p2[i]]++,s[pa[i]]-=2,sum++;
for(i=n;i>=1;i--)
{
s[fa[q[i]]]+=s[q[i]];
if(v[q[i]]>=maxx-sta&&s[q[i]]==sum) return 1;
}
return 0;
}
int main()
{
n=readin(),m=readin();
memset(head,-1,sizeof(head));
int i,j,a,b,c;
for(i=1;i<n;i++)
{
a=readin(),b=readin(),c=readin();
add(a,b,c),add(b,a,c),minn=max(minn,c);
}
deep[1]=top[1]=1;
dfs1(1);
for(i=1;i<=n;i++) //用DFS序
{
if(q[i]==son[fa[q[i]]]) top[q[i]]=top[fa[q[i]]];
else top[q[i]]=q[i];
}
for(i=1;i<=m;i++) //预处理
{
p1[i]=readin(),p2[i]=readin();
pa[i]=getlca(p1[i],p2[i]);
len[i]=dis[p1[i]]+dis[p2[i]]-2*dis[pa[i]];
maxx=max(maxx,len[i]);
}
int l=maxx-minn,r=maxx+1,mid; //缩小范围
while(l<r)
{
mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
printf("%d",r);
return 0;
}

[NOIP2015]运输计划 D2 T3 LCA+二分答案+差分数组的更多相关文章

  1. cogs 2109. [NOIP 2015] 运输计划 提高组Day2T3 树链剖分求LCA 二分答案 差分

    2109. [NOIP 2015] 运输计划 ★★★☆   输入文件:transport.in   输出文件:transport.out   简单对比时间限制:3 s   内存限制:256 MB [题 ...

  2. BZOJ 4326 NOIP2015 运输计划(树上差分+LCA+二分答案)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MB Submit: 1388  Solved: 860 [Submit][Stat ...

  3. NOIP2015 运输计划(二分+LCA+差分)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 308  Solved: 208[Submit][Status] ...

  4. BZOJ 4326:NOIP2015 运输计划(二分+差分+lca)

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

  5. LOJ2425 NOIP2015 运输计划 【二分+LCA+树上差分】*

    LOJ2425 NOIP2015 运输计划 LINK 题意:给你一颗树,可以将任意一条边的权值变成0,然后求m条路径的长度的最小值 思路: 先二分最后的距离ans,然后我们把路程大于ans的所有路径拿 ...

  6. BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1930  Solved: 1231[Submit][Statu ...

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

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

  8. NOIP2015 运输计划(bzoj4326)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 886  Solved: 574[Submit][Status] ...

  9. cogs2109 [NOIP2015] 运输计划

    cogs2109 [NOIP2015] 运输计划 二分答案+树上差分. STO链剖巨佬们我不会(太虚伪了吧 首先二分一个答案,下界为0,上界为max{路径长度}. 然后判断一个答案是否可行,这里用到树 ...

随机推荐

  1. Swift - LineChart绘制折线图

    LineChart,就使用Core Graphics和QuartzCore框架中的CAShapeLayer绘制.这样执行效率明显比堆砌UIView的方法效率高--占用资源少,执行快. 看看CALaye ...

  2. 快速反编绎jar war包

    反编译这些class文件或jar包或war包,用TTools https://github.com/Supermax197/TTools [root@ok action]# tree /home/ok ...

  3. C#的lock关键字

    using System; using System.Threading; namespace Test { class Program { //一.Lock定义 //lock 关键字可以用来确保代码 ...

  4. Redis不同数据类型的的数据结构实现

    我们知道Redis支持五种数据类型, 分别是字符串.哈希表(map).列表(list).集合(set)和有序集合,和Java的集合框架类似,不同数据类型的数据结构实也是不一样的. >>Re ...

  5. Netty网络编程之NIO概览与简单应用

    >>关于NIO Java NIO即Java Non-blocking IO(Java非阻塞I/O),是Jdk1.4之后增加的一套操作I/O工具包,又被叫做Java New IO. (1)R ...

  6. sql server 用户'sa'登录失败(错误18456)(转载)

    转载地址:http://thenear.blog.51cto.com/4686262/865544 用户'sa'登录失败(错误18456)解决方案图解 当我们在使用sql server 的时候可能会遇 ...

  7. Python 打包程序判断是否已经运行

    代码如下: # -*- coding: UTF8 -*- from win32com.client import Dispatch import win32com import sys, os fro ...

  8. Jquery自定义图片上传插件

    1 概述 编写后台网站程序大多数用到文件上传,可是传统的文件上传控件不是外观不够优雅,就是性能不太好看,翻阅众多文件上传控件的文章,发现可以这样去定义一个文件上传控件,实现的文件上传的效果图如下: 2 ...

  9. poj 3278:Catch That Cow(简单一维广搜)

    Catch That Cow Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 45648   Accepted: 14310 ...

  10. 华为Mate8 NFC 时好时坏,怎么解决呢?

    拿起手机朝桌子上磕几下,nfc就好用了.这是花粉总结的,我也试过,很灵.注意要带套,摄像头朝下,头部低一点往下磕.因为nfc芯片在头部,估计是接触不良.