P2680 运输计划  题目

这道题如果是看的我的树上差分来的,那么肯定一看题目就可以想到树上差分.

至于这是怎么想到的,一步一步来:

1.n有300000,不可能暴力枚举每一条边

2.因为我们要使运输时间的最大值最小,所以,考虑二分答案(做多了之后的习惯(其实也就是突然的灵感,不是必然......))

3.既然二分了答案,暂且把我们二分的答案变量名叫 lim ,考虑On的check():

想到每次把超过lim(跑LCA求运输计划的时间)的运输计划全部要考虑删边(显然),并且这些计划都必须要删一条公共边(也是显然,加虫洞就相当于把边权变为0,姑且叫做删边把),这就可以考虑差分了,把超过lim的计划全部差分进去,统计一下差分数组,枚举所有计划都经过的边(也就是差分数组==超过lim的计划数),看看最大的运输代价减去这个边权(相当于把它变为0,显然)是否小于lim, return1/0(显然最大值都小于lim了,所有的都小于lim了); 完成check()!

上代码:

  1. #include<iostream>
  2. #include<cstdlib>
  3. #include<cstdio>
  4. #include<cmath>
  5. #include<cstring>
  6. #include<algorithm>
  7. #include<iomanip>
  8. #include<ctime>
  9. #include<queue>
  10. #include<stack>
  11. #define rg register
  12. #define lst long long
  13. #define N 300050
  14. using namespace std;
  15.  
  16. int n,m,cnt,ans,maxn,le,ri;
  17. struct EDGE{
  18. int to,v,nxt;
  19. }edge[N<<];
  20. struct ROAD{
  21. int fm,to,v;
  22. }road[N];
  23. int head[N],back[N];
  24. int cf[N];
  25. int deep[N],fa[N];
  26. int f[N][],g[N][];
  27.  
  28. inline int read()
  29. {
  30. rg int s=,m=;rg char ch=getchar();
  31. while(ch!='-'&&(ch<''||ch>''))ch=getchar();
  32. if(ch=='-')m=-,ch=getchar();
  33. while(ch>=''&&ch<='')s=(s<<)+(s<<)+ch-'',ch=getchar();
  34. return s*m;
  35. }
  36.  
  37. inline void add(rg int p,rg int q,rg int o)
  38. {
  39. edge[++cnt].to=q,edge[cnt].v=o;
  40. edge[cnt].nxt=head[p];
  41. head[p]=cnt;
  42. }
  43.  
  44. void dfs(rg int now,rg int fm,rg int dep,rg int s)//dfs预处理倍增LCA
  45. {
  46. fa[now]=fm,deep[now]=dep;
  47. f[now][]=fm;g[now][]=s;
  48. for(rg int i=;i<=;++i)
  49. {
  50. f[now][i]=f[f[now][i-]][i-];
  51. g[now][i]=g[f[now][i-]][i-]+g[now][i-];
  52. }
  53. for(rg int i=head[now];i;i=edge[i].nxt)
  54. {
  55. rg int qw=edge[i].to;
  56. if(qw!=fm)
  57. {
  58. back[qw]=i;
  59. dfs(qw,now,dep+,edge[i].v);
  60. }
  61. }
  62. }
  63.  
  64. inline int LCA(rg int x,rg int y,rg int op)//倍增跳LCA
  65. {
  66. rg int res=;
  67. if(deep[x]<deep[y])swap(x,y);
  68. while(deep[x]>deep[y])//跳到同样深度
  69. for(rg int i=;i>=;--i)
  70. if(deep[f[x][i]]>=deep[y])res+=g[x][i],x=f[x][i];
  71.  
  72. while(x!=y)
  73. {
  74. for(rg int i=;i>=;--i)
  75. if(f[x][i]!=f[y][i])
  76. res+=g[x][i]+g[y][i],x=f[x][i],y=f[y][i];
  77.  
  78. if(fa[x]==fa[y])res+=g[x][]+g[y][],x=y=fa[x];
  79. }
  80. if(!op)return res;
  81. else return x;
  82. }
  83.  
  84. inline void Insert(rg int p,rg int q)//差分
  85. {
  86. rg int lca=LCA(p,q,);
  87. cf[p]++,cf[q]++,cf[lca]-=;
  88. }
  89.  
  90. void sum(rg int now)//统计差分数组
  91. {
  92. for(rg int i=head[now];i;i=edge[i].nxt)
  93. {
  94. rg int qw=edge[i].to;
  95. if(qw!=fa[now])
  96. {
  97. sum(qw);
  98. cf[now]+=cf[qw];
  99. }
  100. }
  101. }
  102.  
  103. inline int check(rg int lim)//如解析,check()
  104. {
  105. rg int ss=,Max=;
  106. for(rg int i=;i<=n;++i)cf[i]=;
  107. for(rg int i=;i<=m;++i)
  108. {
  109. if(road[i].v>lim)
  110. {
  111. Max=max(Max,road[i].v);
  112. ss++,Insert(road[i].fm,road[i].to);
  113. }
  114. }
  115. sum();
  116. for(rg int i=;i<=n;++i)
  117. if(cf[i]==ss&&Max-edge[back[i]].v<=lim)return ;
  118. return ;
  119. }
  120.  
  121. int main()
  122. {
  123. n=read(),m=read();
  124. for(rg int i=;i<n;++i)
  125. {
  126. rg int p=read(),q=read(),o=read();
  127. add(p,q,o),add(q,p,o);
  128. }
  129. //读入边的信息
  130. dfs(,,,);
  131. for(rg int i=;i<=m;++i)
  132. {
  133. rg int p=read(),q=read();
  134. road[i].fm=p,road[i].to=q,road[i].v=LCA(p,q,);
  135. ri=max(ri,road[i].v);
  136. }
  137. add(,,);//没事干加了一个 0->1 的边,感觉比较踏实(0的父亲是1)...无语...
  138. while(le<=ri)//二分
  139. {
  140. rg int mid=(ri+le)>>;
  141. if(check(mid))ans=mid,ri=mid-;
  142. else le=mid+;
  143. }
  144. printf("%d\n",ans);
  145. return ;
  146. }

luoguP2680 运输计划 题解(二分答案+树上差分)的更多相关文章

  1. luogu2680 [NOIp2015]运输计划 (tarjanLca+二分答案+树上差分)

    我们先不会就二分一下答案,设它是x,我们要判断它能不能满足 为了满足这个答案,我们就要让原本路径长度大于x的所有路径都经过某条边,而且这条边还要大于等于最长的路径-x 于是运用树上差分的思想,对于所有 ...

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

    题目链接  BZOJ4326 这个程序在洛谷上TLE了……惨遭卡常 在NOIP赛场上估计只能拿到95分吧= = 把边权转化成点权 首先求出每一条路径的长度 考虑二分答案,$check(now)$ 对于 ...

  3. bzoj4326: NOIP2015 运输计划(二分+LCA+树上差分)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4326 题目大意:有一颗含有n个顶点的树,每两个点之间有一个边权,现在有m个运输计划,每个 ...

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

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

  5. NOIP2015运输计划(二分答案)

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

  6. [luogu]P2680 运输计划[二分答案][树上差分]

    [luogu]P2680 [NOIP2015]运输计划 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n ...

  7. luogu P2680 运输计划 (二分答案+树上差分)

    题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条航道建立在两个星球之间 ...

  8. loj2425 「NOIP2015」运输计划[二分答案+树上差分]

    看到题意最小化最长路径,显然二分答案,枚举链长度不超过$\text{mid}$,然后尝试检验.````` 检验是否存在这样一个边置为0后,全部链长$\le\text{mid}$,其最终目标就是.要让所 ...

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

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

随机推荐

  1. elasticsearch 基础 —— ReIndex

    Reindex会将一个索引的数据复制到另一个已存在的索引,但是并不会复制原索引的mapping(映射).shard(分片).replicas(副本)等配置信息. 一.reindex的常用操作 1.re ...

  2. 202-基于TI DSP TMS320C6678、Xilinx K7 FPGA XC72K325T的高速数据处理核心板

    基于TI DSP TMS320C6678.Xilinx K7 FPGA XC72K325T的高速数据处理核心板 一.板卡概述 该DSP+FPGA高速信号采集处理板由我公司自主研发,包含一片TI DSP ...

  3. Codeforces 722E 组合数学 DP

    题意:有一个n * m的棋盘,你初始在点(1, 1),你需要去点(n, m).你初始有s分,在这个棋盘上有k个点,经过一次这个点分数就会变为s / 2(向上取整),问从起点到终点的分数的数学期望是多少 ...

  4. Codeforces Round #584 - Dasha Code Championship - Elimination Round (rated, open for everyone, Div. 1 + Div. 2)

    怎么老是垫底啊. 不高兴. 似乎 A 掉一道题总比别人慢一些. A. Paint the Numbers 贪心,从小到大枚举,如果没有被涂色,就新增一个颜色把自己和倍数都涂上. #include< ...

  5. Java打印流学习

    打印流 打印流的主要功能是用于输出,在整个IO包打印流分为两种类型,打印流可以很方便的进行输出. 1.字节打印流:PrintStream(在字节输出时,可以增强输出功能) 2.字符打印流:PrintW ...

  6. 存储过程如何传变量到like下

    存储过程中执行如下DDL语句create or replace procedure etl_test(v_com varchar2) is v_spname varchar2(40); com var ...

  7. redisTemplate 封装bitcout

    @Repositorypublic class RedisServiceExtend { @Autowired private RedisTemplate<String, String> ...

  8. 分布式架构的CAP原理

    CAP 定理的含义   一.分布式系统的三个指标 1998年,加州大学的计算机科学家 Eric Brewer 提出,分布式系统有三个指标. Consistency Availability Parti ...

  9. html中 的method=post和method=get的区别

    1. get是从服务器上获取数据,post是向服务器传送数据. 2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到.post是通过 ...

  10. CDH6.3 Centos7

    按照官方文档安装即可 CentOS7 上搭建 CDH(6.3.0) 官方文档:https://docs.cloudera.com/documentation/enterprise/6/6.3/topi ...