bzoj 4326: NOIP2015 运输计划
4326: NOIP2015 运输计划
Time Limit: 30 Sec Memory Limit: 128 MB
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。数据保证 1≤ai,bi≤n 且 0≤ti≤1000。接下来 m 行描述运输计划的情况,其中第 j 行包含两个正整数 uj 和 vj,表示第 j 个运输计划是从 uj 号星球飞往 vj号星球。数据保证 1≤ui,vi≤n
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
题目分析
当初联赛此题我看都来得及没看,好弱啊。当初听学长说此题是一道树剖,本蒟蒻现在学了树剖还是不会。
首先,此题要求最大值最小,容易可以想到二分。
现在要想如何\(check\)。
显然,要变为虫洞的边应该在所有比\(mid\)值大的路径上,于是我们需要快速求出所有这类路径的交集上的最大边。
我们可以用差分来进行求交集,之后乱搞一下就好了。
代码比较丑,用时8500ms+
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
//Input
int ina; char inc,inb[1<<16],*ine=inb,*ins=inb;
#define getc() ((ins==ine&&(ine=(ins=inb)+fread(inb,1,1<<16,stdin),ins==ine))?EOF:*ins++)
inline int geti() {
while((inc=getc())<'0'||inc>'9'); ina=inc-'0';
while((inc=getc())>='0'&&inc<='9') ina=(ina<<3)+(ina<<1)+inc-'0';
return ina;
}
//Tree
#define N 300010
int son[N],fa[N],top[N],head[N],nxt[N<<1],to[N<<1],w[N<<1],tote,dep[N],dis[N],d[N];
#define FOR(a,b) for(int a=head[b];~a;a=nxt[a])
int dfs1(int u) {
int ret=1,t,mx=0; son[u]=0;
FOR(i,u) if(to[i]^fa[u]) {
dep[to[i]]=dep[u]+1;
dis[to[i]]=dis[u]+w[i];
fa[to[i]]=u;
ret +=(t=dfs1(to[i]));
(mx<t)?mx=t,son[u]=to[i]:1;
}
return ret;
}
void dfs2(int u,int tp) {
top[u]=tp; if(son[u]) dfs2(son[u],tp);
FOR(i,u) if(to[i]!=fa[u]&&to[i]!=son[u])
dfs2(to[i],to[i]);
}
int lca(int u,int v) {
while(top[u]^top[v]) {
if(dep[top[u]]<dep[top[v]]) u^=v^=u^=v;
u=fa[top[u]];
}
return (dep[u]<dep[v])?u:v;
}
//Operator
int From[N],End[N],Len[N],Lca[N];
//main
int mxdis,mxedge,cntmor,val[N],n,m;
int rejudge(int u) {
FOR(i,u) if(to[i]^fa[u]) d[u]+=rejudge(to[i]);
(d[u]==cntmor&&mxedge<val[u])?mxedge=val[u]:1;
return d[u];
}
bool check(int x) {
mxdis=mxedge=cntmor=0;
memset(d,0,sizeof d);
for(int i=1;i<=m;++i) if(Len[i]>x) {
(mxdis<Len[i])?mxdis=Len[i]:1;
++d[From[i]],++d[End[i]];
d[Lca[i]]-=2; ++cntmor;
}
rejudge(1);
return mxdis-mxedge<=x;
}
int main() {
int i,j,k,a,b,c,l,r=0,mid,ans;
memset(head,-1,sizeof head);
for(n=geti(),m=geti(),i=1;i<n;++i) {
a=geti(),b=geti(),c=geti();
to[tote]=b,nxt[tote]=head[a],w[tote]=c,head[a]=tote++;
to[tote]=a,nxt[tote]=head[b],w[tote]=c,head[b]=tote++;
}
dfs1(1), dfs2(1,1);
for(i=0;i<tote;i+=2) val[(dep[to[i]]<dep[to[i^1]])?to[i^1]:to[i]]=w[i];
for(i=1;i<=m;++i) {
From[i]=geti(),End[i]=geti();
Len[i]=dis[From[i]]+dis[End[i]]-2*dis[Lca[i]=lca(From[i],End[i])];
(r<Len[i])?r=Len[i]:1;
}
l=0;
while(l<=r) {
mid=l+r>>1;
if(check(mid)) r=(ans=mid)-1;
else l=mid+1;
}
return printf("%d\n",ans),0;
}
update:
此代码在洛谷(被某人刷贴之后管理员改时限过了)和CodeVs(非官方数据)上被卡掉了,似乎用tarjan可过,不过不想改了。
bzoj 4326: NOIP2015 运输计划的更多相关文章
- BZOJ 4326 NOIP2015 运输计划(树上差分+LCA+二分答案)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MB Submit: 1388 Solved: 860 [Submit][Stat ...
- BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1930 Solved: 1231[Submit][Statu ...
- bzoj 4326: NOIP2015 运输计划(二分+树链剖分)
传送门 题解: 树链剖分快速求解任意两点间的路径的权值和: 然后,二分答案: 此题的难点是如何快速求解重合路径? 差分数组可以否??? 在此之前先介绍一下相关变量: int fa[maxn]; int ...
- BZOJ 4326: NOIP2015 运输计划(二分,树上差分)
Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 1945 Solved: 1243[Submit][Status][Discuss] Descript ...
- bzoj 4326: NOIP2015 运输计划【树链剖分+二分+树上差分】
常数巨大,lg上开o2才能A 首先预处理出运输计划的长度len和lca,然后二分一个长度w,对于长度大于w的运输计划,在树上差分(d[u]+1,d[v]+1,d[lca]-2),然后dfs,找出所有覆 ...
- BZOJ 4326 NOIP2015 运输计划(二分答案 + 树上差分思想)
题目链接 BZOJ4326 这个程序在洛谷上TLE了……惨遭卡常 在NOIP赛场上估计只能拿到95分吧= = 把边权转化成点权 首先求出每一条路径的长度 考虑二分答案,$check(now)$ 对于 ...
- NOIP2015 运输计划(二分+LCA+差分)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 308 Solved: 208[Submit][Status] ...
- NOIP2015 运输计划(bzoj4326)
4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MBSubmit: 886 Solved: 574[Submit][Status] ...
- BZOJ 4326:NOIP2015 运输计划(二分+差分+lca)
NOIP2015 运输计划Description公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所 ...
随机推荐
- 有了大量微信用户,就不需要App了吗?
小卢同学是我半年前在中关村车库咖啡认识的一个自由创业者,他从北航毕业后在一家IT上市公司只上了1年多的班就辞职创业了,他的创业项目属于国内度假旅游垂直细分领域:积累大量详细的旅游攻略,组成一个个温馨舒 ...
- iOS从零开始学习直播之音频1.播放本地音频文件
现在直播越来越火,俨然已经成为了下一个红海.作为一个资深码农(我只喜欢这样称呼自己,不喜欢别人这样称呼我),我必须赶上时代的潮流,开始研究视频直播.发现视屏直播类的文章上来就讲拉流.推流.采集.美 ...
- audio 基本功能实现(audio停止播放,audio如何静音,audio音量控制等)
audio最简单原始的播放.暂停.停止.静音.音量大小控制的功能,注意某些浏览器会有权限无法自动播放噢(video也会如此) <!doctype html> <html> &l ...
- seL4之hello-3征途
seL4之hello-3征途 回顾上周 了解seL4的启动流程和初始化线程 了解seL4的几种内核对象和权能机制 完成hell0-2的运行. 补充上周 1.找到根任务(初始化线程)的创建具体的位置(那 ...
- 完全删除TFS2013上的项目
必备条件:您必须是 Team Foundation Server Administrators 组的成员或待删除项目的 Project Administrators 组的成员. 解决方法:打开&quo ...
- Python中获取当前日期的格式
在Python里如何获取当前的日期和时间呢?在Python语言里,我们可以通过调用什么模块或者类函数来得到当前的时间或日期呢? 当然你可以使用时间模块(time module),该模块提供了各种和时间 ...
- 0041 Java学习笔记-多线程-线程池、ForkJoinPool、ThreadLocal
什么是线程池 创建线程,因为涉及到跟操作系统交互,比较耗费资源.如果要创建大量的线程,而每个线程的生存期又很短,这时候就应该使用线程池了,就像数据库的连接池一样,预先开启一定数量的线程,有任务了就将任 ...
- python编码最佳实践之总结
相信用python的同学不少,本人也一直对python情有独钟,毫无疑问python作为一门解释性动态语言没有那些编译型语言高效,但是python简洁.易读以及可扩展性等特性使得它大受青睐. 工作中很 ...
- ACCELEROMETER
顾名思义,是加速感应器.有2种应用吧:1,电脑保护,例如当笔记本掉落时,可以被自动检测到,此时会自动关闭硬盘操作以保护数据不在强烈冲击时丢失.
- list<T> 的使用方法。
首先讲一个经常用到的Contains( )方法,用来测试一个元素是否在List内.这个功能跟SQL里面的" like % %"类似. 这个方法在数组中也存在,因为集合其实就是动态数 ...