运输计划
(transport.cpp/c/pas)
【问题描述】
公元 2044 年,人类进入了宇宙纪元。L 国有 n 个星球,还有 n-1 条 双向 航道,每条航道建立在两个星球之间,这 n-1 条航道 连通 了 L 国的所有星球。
小 P 掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 u i 号星球沿 最快 的宇航路径飞行到 v i 号星球去。显然,飞船驶过一条航道是需要时间的,对于航道 j,任意飞船驶过它所花费的时间为 t j ,并且任意两艘飞船之间 不会 产生任何干扰。
为了鼓励科技创新,L 国国王同意小 P 的物流公司参与 L 国的航道建设,即允许小P 把某一条航道改造成虫洞,飞船驶过虫洞 不消耗 时间。在虫洞的建设完成前小 P 的物流公司就预接了 m 个运输计划。在虫洞建设完成后,这 m 个运输计划会 同时 开始,所有飞船 一起 出发。当这 m 个运输计划 都完成 时,小 P 的物流公司的阶段性工作就完成了。如果小 P 可以 自由选择 将哪一条航道改造成虫洞,试求出小 P 的物流公司完成阶段性工作所需要的最短时间是多少?
【输入格式】
输入文件名为 transport.in。
第一行包括两个正整数 n、 m,表示 L 国中星球的数量及小 P 公司预接的运输计划的数量,星球从 1 到 n 编号。
接下来 n-1 行描述航道的建设情况,其中第 i 行包含三个整数 a i , b i 和 t i ,表示第i 条双向航道修建在 a i 与 b i 两个星球之间,任意飞船驶过它所花费的时间为 t i 。
接下来 m 行描述运输计划的情况,其中第 j 行包含两个正整数 u j 和 v j ,表示第 j 个运输计划是从 u j 号星球飞往 v j 号星球。
【输出格式】
输出文件名为 transport.out。
共 1 行,包含 1 个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间。

正解:树链剖分+二分答案+差分

解题报告:

  NOIP2015的原题,还记得这道题当年的考场上打的是倍增的暴力。。。

  首先链剖,并预处理一下每个计划的原始距离。二分一个答案x,找出所有距离大于x的计划,单独处理。显然我们需要使这些计划的总时间都要变少,那么我们必须要找出一条边被这所有的超时的计划所包含,并尽可能的使这条边的权值大,这样的话,我们可以考虑把边被经过的次数差分,所有计划求lca的时候顺便差分一下,标记一下经过的边。最后一遍统计每条边的经过次数,如果刚好等于超时的计划,我们才考虑这条边是否可以产生贡献,如果至少有一个计划不满足,无论如何不可能。最后只需要比较一下这条边能否使时间最大的计划完成即可完成可行性判断。

  代码如下:

 //It is made by jump~
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <ctime>
using namespace std;
typedef long long LL;
#define RG register
const int MAXN = ;
const int MAXM = ;
int n,m,ecnt,Max,ans,cnt;
int first[MAXN],to[MAXN*],next[MAXN*],w[MAXN*];
int deep[MAXN],top[MAXN],size[MAXN],son[MAXN],father[MAXN],id[MAXN],sum[MAXN],quan[MAXN];
int b[MAXN];//差分数组,统计经过某条边的次数
int l,r,root;
struct fight{
int u,v;
int dis;
}a[MAXM]; inline int getint()
{
RG int w=,q=; char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
} inline void dfs(RG int x,RG int fa){
size[x]=;
for(RG int i=first[x];i;i=next[i]) {
RG int v=to[i]; if(v==fa) continue;
quan[v]=w[i];
deep[v]=deep[x]+; father[v]=x; dfs(v,x); size[x]+=size[v];
if(size[v]>=size[son[x]]) son[x]=v;
}
} inline void dfs2(RG int x,RG int fa){
id[x]=++ecnt; sum[ecnt]=sum[ecnt-]+quan[x];
if(son[x]) top[son[x]]=top[x],dfs2(son[x],x);
for(RG int i=first[x];i;i=next[i]) {
RG int v=to[i]; if(v==fa || v==son[x]) continue;
top[v]=v; dfs2(v,x);
}
} inline void lca(RG int now){
RG int x=a[now].u,y=a[now].v;
RG int f1=top[x],f2=top[y];
while(f1!=f2) {
if(deep[f1]<deep[f2]) swap(f1,f2),swap(x,y);
a[now].dis+=sum[id[x]]-sum[id[f1]-];
x=father[f1]; f1=top[x];
}
if(deep[x]<deep[y]) swap(x,y);
a[now].dis+=sum[id[x]]-sum[id[son[y]]-];//应该是son[y],因为到y为止是y连了y在内的
} inline void update(RG int now){
RG int x=a[now].u,y=a[now].v;
RG int f1=top[x],f2=top[y];
while(f1!=f2) {
if(deep[f1]<deep[f2]) swap(f1,f2),swap(x,y);
b[id[f1]]++; b[id[x]+]--;
x=father[f1]; f1=top[x];
}
if(deep[x]<deep[y]) swap(x,y);
b[id[son[y]]]++; b[id[x]+]--;//+1
} inline bool check(RG int x){
cnt=;//统计不能在规定时间内完成的
memset(b,,sizeof(b));
RG int cost=;
for(RG int i=;i<=n;i++) {
if(a[i].dis>x) {
cnt++; cost=max(cost,a[i].dis-x);
update(i);
}
}
RG int zuida=,now=;
for(RG int i=;i<=n;i++) {//讨论的是结点编号,而不是结点本身!
now+=b[i];
if(now==cnt) {//必须是覆盖了所有,否则的话就没有用
zuida=max(sum[i]-sum[i-],zuida);
}
}
if(zuida>=cost) return true;
return false;
} inline void work(){
//srand(time(NULL));
n=getint(); m=getint(); RG int x,y,z;
for(RG int i=;i<n;i++) {
x=getint(); y=getint(); z=getint(); Max+=z;
next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; w[ecnt]=z;
next[++ecnt]=first[y]; first[y]=ecnt; to[ecnt]=x; w[ecnt]=z;
}
//root=rand()%n+1;
root=n/;
deep[root]=; dfs(root,);
ecnt=; top[root]=root; dfs2(root,); RG int mid;
for(RG int i=;i<=m;i++) a[i].u=getint(),a[i].v=getint(),lca(i);
l=; r=Max;
ans=;
while(l<=r) {
mid=(l+r)/;
if(check(mid)) ans=mid,r=mid-;
else l=mid+;
}
printf("%d",ans);
} int main()
{
work();
return ;
}

UOJ150 运输计划的更多相关文章

  1. bzoj 4326: NOIP2015 运输计划

    4326: NOIP2015 运输计划 Time Limit: 30 Sec Memory Limit: 128 MB Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个 ...

  2. noip2015 运输计划

    描述 公元 2044 年,人类进入了宇宙纪元.L 国有 nn 个星球,还有 n−1n−1 条双向航道,每条航道建立在两个星球之间,这 n−1n−1 条 航道连通了 L 国的所有星球. 小 P 掌管一家 ...

  3. 【bzoj4326】[NOIP2015]运输计划

    题目描述 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家物流公司, 该 ...

  4. [题解]vijos 运输计划

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

  5. NOIP2015 运输计划(bzoj4326)

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

  6. UOJ #150 【NOIP2015】 运输计划

    题目描述 公元 \(2044\) 年,人类进入了宇宙纪元. \(L\) 国有 \(n\) 个星球,还有 \(n-1\) 条双向航道,每条航道建立在两个星球之间,这 \(n-1\) 条航道连通了 \(L ...

  7. [bzoj4326][NOIP2015]运输计划

    Description 公元2044年,人类进入了宇宙纪元. 国有个星球,还有条双向航道,每条航道建立在两个星球之间,这条航道连通了国的所有星球. 小掌管一家物流公司,该公司有很多个运输计划,每个运输 ...

  8. 【BZOJ-4326】运输计划 树链剖分 + 树上差分 + 二分

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

  9. [NOIP2015] 提高组 洛谷P2680 运输计划

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

随机推荐

  1. C#中treeview的问题,如何区分根节点和子节点以及根节点和根节点的兄弟节点?

    根节点的Level属性为0,一级子节点Level属性为1,二级子节点Level属性为2,以此类推:同级节点可以用索引.名称.文本来区分.用索引区分根节点时,TreeView.Nodes[0]就是第一个 ...

  2. javascript中的array对象属性及方法

    Array 对象 Array 对象用于在单个的变量中存储多个值. 创建 Array 对象的语法: new Array(); new Array(size); new Array(element0, e ...

  3. usb驱动开发9之设备描述符

    前面分析了usb的四大描述符之端点描述符,接口描述符(每一个接口对应一个功能,与之配备相应驱动),配置描述符,最后分析设备如何包括这些描述符.首先记住,在usb的世界里,设备大于配置,配置大于接口,接 ...

  4. HTTP基础(一):如何使用浏览器network查看请求和响应的信息

    一. 问题描述 HTTP作为前端开发与后开发链接的载体,其重要性不言而喻,今天我不复习关于HTTP自身的一些知识,只复习如何解读浏览器自带的的抓包工具(查看请求信息与响应信息)network. 二. ...

  5. Caffe学习系列(17):模型各层数据和参数可视化

    cifar10的各层数据和参数可视化 .caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1p ...

  6. 让Java说话-用Java实现语音引擎

    让Java说话-用Java实现语音引擎 2005-11-07 10:04:09 分类: Java技术 为应用程序加上语音能力有什么好处呢?粗略地讲,是为了趣味,它适合所有注重趣味的应用,比如游戏.当然 ...

  7. Android nDrawer

    GitHub上一款流行的侧滑,附上自己as编译过的源码http://download.csdn.net/detail/lj419855402/8559039. 留个纪念,说不定以后用得到. 依赖一个l ...

  8. C++系列: 如何将十六机制的字符串转成整数

    bool convertHexStringToInt(char* pstrHex, unsigned long* pResult) { ) return false; else return true ...

  9. JS闭包的理解

    闭包的两个特点: 1.作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态.2.一个闭包就是当一个函数返回时,一个没有释放资源的栈区. 其实上面两点可以合成一点,就是闭包函数返回时,该函数内部 ...

  10. Linux及安全——Linux基础实践

    Linux及安全——Linux基础实践 一.实践一:掌握软件源的维护方法,配置系统使用教育网内的软件源镜像.掌握通过软件源来查找,安装,卸载,更新软件的方法. 1.软件源的维护方法 Ubuntu的软件 ...