运输计划
(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. Android Studio系列教程二--基本设置与运行

    Android Studio系列教程二--基本设置与运行 2014 年 11 月 28 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处! 上面一篇博客,介绍了Studio的 ...

  2. bean的作用域

    bean的作用域为singleton,spring容器中只存在一个bean的实例,所有对该bean的请求只返回同一个bean实例. 当bean的作用域为prototype时,每一次对bean的请求,都 ...

  3. 【转】【C#】ColorMatrix

    ColorMatrix(色彩矩阵),是GDI+里用来调整图片色彩的矩阵. 什么是矩阵,说白了就是C#里的二维数组. 那么这个矩阵调整色彩的原理是什么,他是怎么来调整色彩的呢?这个要从线性代数里的矩阵相 ...

  4. 替换空格-请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

    class Solution { public: void replaceSpace(char *str,int length) { char *tmp; ; int i; ;i<length; ...

  5. C语言 预处理二(宏定义--#define)

    //#define 宏定义(宏定义一般大写) //知识点一-->#define的作用域:从#define开始,从上往下,如果遇到#undef就到#undef处结束,如果没有就是作用于当前整个文件 ...

  6. U3D assetbundle加载与卸载的深入理解

    using UnityEngine; using System.Collections; using System; public class testLoadFromAB : MonoBehavio ...

  7. C++哈弗曼编码

    // haffman.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> using name ...

  8. Eclipse中10个最有用的快捷键组合(转)

    Eclipse中10个最有用的快捷键组合 1. ctrl+shift+r:打开资源 这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask ...

  9. 淘宝账号基于OAuth2.0的登录验证授权登陆第三方网站

    首先得有一个注册的appkey和App Secret   该流程分三个步骤: 第一步:通过用户授权获取授权码Code: 第二步:用上一步获取的Code和应用密钥(AppSecret)通过Https P ...

  10. 【转】使用sklearn优雅地进行数据挖掘

    这里是原文 目录 使用sklearn进行数据挖掘 1.1 数据挖掘的步骤 1.2 数据初貌 1.3 关键技术并行处理 并行处理 2.1 整体并行处理 2.2 部分并行处理流水线处理自动化调参持久化回顾 ...