运输计划
(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的时候顺便差分一下,标记一下经过的边。最后一遍统计每条边的经过次数,如果刚好等于超时的计划,我们才考虑这条边是否可以产生贡献,如果至少有一个计划不满足,无论如何不可能。最后只需要比较一下这条边能否使时间最大的计划完成即可完成可行性判断。

  代码如下:

  1. //It is made by jump~
  2. #include <iostream>
  3. #include <cstring>
  4. #include <cstdio>
  5. #include <algorithm>
  6. #include <ctime>
  7. using namespace std;
  8. typedef long long LL;
  9. #define RG register
  10. const int MAXN = ;
  11. const int MAXM = ;
  12. int n,m,ecnt,Max,ans,cnt;
  13. int first[MAXN],to[MAXN*],next[MAXN*],w[MAXN*];
  14. int deep[MAXN],top[MAXN],size[MAXN],son[MAXN],father[MAXN],id[MAXN],sum[MAXN],quan[MAXN];
  15. int b[MAXN];//差分数组,统计经过某条边的次数
  16. int l,r,root;
  17. struct fight{
  18. int u,v;
  19. int dis;
  20. }a[MAXM];
  21.  
  22. inline int getint()
  23. {
  24. RG int w=,q=; char c=getchar();
  25. while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
  26. while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
  27. }
  28.  
  29. inline void dfs(RG int x,RG int fa){
  30. size[x]=;
  31. for(RG int i=first[x];i;i=next[i]) {
  32. RG int v=to[i]; if(v==fa) continue;
  33. quan[v]=w[i];
  34. deep[v]=deep[x]+; father[v]=x; dfs(v,x); size[x]+=size[v];
  35. if(size[v]>=size[son[x]]) son[x]=v;
  36. }
  37. }
  38.  
  39. inline void dfs2(RG int x,RG int fa){
  40. id[x]=++ecnt; sum[ecnt]=sum[ecnt-]+quan[x];
  41. if(son[x]) top[son[x]]=top[x],dfs2(son[x],x);
  42. for(RG int i=first[x];i;i=next[i]) {
  43. RG int v=to[i]; if(v==fa || v==son[x]) continue;
  44. top[v]=v; dfs2(v,x);
  45. }
  46. }
  47.  
  48. inline void lca(RG int now){
  49. RG int x=a[now].u,y=a[now].v;
  50. RG int f1=top[x],f2=top[y];
  51. while(f1!=f2) {
  52. if(deep[f1]<deep[f2]) swap(f1,f2),swap(x,y);
  53. a[now].dis+=sum[id[x]]-sum[id[f1]-];
  54. x=father[f1]; f1=top[x];
  55. }
  56. if(deep[x]<deep[y]) swap(x,y);
  57. a[now].dis+=sum[id[x]]-sum[id[son[y]]-];//应该是son[y],因为到y为止是y连了y在内的
  58. }
  59.  
  60. inline void update(RG int now){
  61. RG int x=a[now].u,y=a[now].v;
  62. RG int f1=top[x],f2=top[y];
  63. while(f1!=f2) {
  64. if(deep[f1]<deep[f2]) swap(f1,f2),swap(x,y);
  65. b[id[f1]]++; b[id[x]+]--;
  66. x=father[f1]; f1=top[x];
  67. }
  68. if(deep[x]<deep[y]) swap(x,y);
  69. b[id[son[y]]]++; b[id[x]+]--;//+1
  70. }
  71.  
  72. inline bool check(RG int x){
  73. cnt=;//统计不能在规定时间内完成的
  74. memset(b,,sizeof(b));
  75. RG int cost=;
  76. for(RG int i=;i<=n;i++) {
  77. if(a[i].dis>x) {
  78. cnt++; cost=max(cost,a[i].dis-x);
  79. update(i);
  80. }
  81. }
  82. RG int zuida=,now=;
  83. for(RG int i=;i<=n;i++) {//讨论的是结点编号,而不是结点本身!
  84. now+=b[i];
  85. if(now==cnt) {//必须是覆盖了所有,否则的话就没有用
  86. zuida=max(sum[i]-sum[i-],zuida);
  87. }
  88. }
  89. if(zuida>=cost) return true;
  90. return false;
  91. }
  92.  
  93. inline void work(){
  94. //srand(time(NULL));
  95. n=getint(); m=getint(); RG int x,y,z;
  96. for(RG int i=;i<n;i++) {
  97. x=getint(); y=getint(); z=getint(); Max+=z;
  98. next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; w[ecnt]=z;
  99. next[++ecnt]=first[y]; first[y]=ecnt; to[ecnt]=x; w[ecnt]=z;
  100. }
  101. //root=rand()%n+1;
  102. root=n/;
  103. deep[root]=; dfs(root,);
  104. ecnt=; top[root]=root; dfs2(root,);
  105.  
  106. RG int mid;
  107. for(RG int i=;i<=m;i++) a[i].u=getint(),a[i].v=getint(),lca(i);
  108. l=; r=Max;
  109. ans=;
  110. while(l<=r) {
  111. mid=(l+r)/;
  112. if(check(mid)) ans=mid,r=mid-;
  113. else l=mid+;
  114. }
  115. printf("%d",ans);
  116. }
  117.  
  118. int main()
  119. {
  120. work();
  121. return ;
  122. }

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. css3爆炸效果更换图片轮播图

    思路:给一个div设置一个背景图片1.jpg,然后在这个div上面用两个for循环动态的创建一个列数为C行数为R数量的span,并给这些span设置宽高.定位并设置背景图片0.jpg,然后设置每个sp ...

  2. spring核心组件

    spring的对象是bean组件,就像面向对象的object,bean包装的是object.context的作用,发现每个bean之间的关系,为他们之间建立好这种关系并进行维护.所以,可以把conte ...

  3. kprobe原理解析(二)

    上一篇文章和大家简要说明了下kprobe到底应该怎样用,那么现在我们就揭开kprobe神秘的面纱,刨根问底,一睹kprobe的庐山真面目. kprobe的工作过程大致如下: 1)注册kprobe.注册 ...

  4. 010医疗项目-模块一:用户添加的实现(Dao,Service,Action,增加页面调试,提交页面调试)

    要实现的效果:

  5. 【C#】【Thread】上下文同步域SynchronizationAttribute

    上下文同步:使用SynchronizationAttribute为ContextBoundObject对象创建一个简单的自动的同步. 这种同步方式仅用于实例化的方法和域的同步.所有在同一个上下文域的对 ...

  6. 移动Web 开发中的一些前端知识收集汇总

    在开发DeveMobile 与EaseMobile 主题 的时候积累了一些移动Web 开发的前端知识,本着记录总结的目的,特写这篇文章备忘一下. 要说移动Web 开发与传统的PC 端开发,感觉也没什么 ...

  7. Nginx支持连接数的问题

    据网上有人说nginx的配置中: nginx支持的最大连接数与以下因素有关: worker_processes ; events { worker_connections ; } ulimit -a ...

  8. 动画:UIKitAnimation 简单动画学习 iOS (一) 渐变 、 移动 、翻页、来回翻转 ——转载

    转载请说明(谢谢) http://blog.csdn.net/a21064346/article/details/7851695 点击打开链接 以下 一个系列的 动画效果 在 UIView.h文件中可 ...

  9. 工作随笔——xshell4安装后应该做的一些事

    xshell4默认支持中文语言 选项→键盘和鼠标:设置快捷键,鼠标按键(可以提高工作效率) 1.选定文本自动复制到剪贴板 选择→将选定的文本自动复制到剪贴板(选上) 2.更高鼠标中间按钮和右键按钮的功 ...

  10. WPF之TreeList的实现方法(一)

    做项目的时候根据需求,WPF现有的控件不能完全满足我们的需求, 很多时候我们需要对现有的控件做一下加工. 最简单的我们可能会把Tree转换成List形式有的叫Grid形式就像下图一样 今天我先做一个完 ...