P2680

题目的大意就是走完m条路径所需要的最短时间(边权是时间), 其中我们可以把一条边的权值变成0(也就是题目所说的虫洞)。

可以考虑二分答案x,找到一条边,使得所有大于x的路径经过这条边(差分维护),并且路径减去这条边的边权后小等于x,通过这样判定x是否可行。

  1. 1 #include <bits/stdc++.h>
  2. 2 #define ll long long
  3. 3 using namespace std;
  4. 4 const int N = 3e5 + 10;
  5. 5 int tot, head[N], to[N << 1], nxt[N << 1], edge[N << 1];
  6. 6 int n, m, fa[N][25], dep[N], dis[N], pre[N], num[N];
  7. 7 struct node {
  8. 8 int x, y, lca;
  9. 9 }q[N];
  10. 10 void add(int x, int y, int z) {
  11. 11 nxt[++ tot] = head[x], head[x] = tot, to[tot] = y, edge[tot] = z;
  12. 12 }
  13. 13 void dfs(int u, int f) {
  14. 14 dep[u] = dep[f] + 1;
  15. 15 fa[u][0] = f;
  16. 16 for (int i = 1; i <= 20; i ++)
  17. 17 fa[u][i] = fa[fa[u][i - 1]][i - 1];
  18. 18 for (int i = head[u]; i; i = nxt[i]) {
  19. 19 int v = to[i];
  20. 20 if (v == f) continue;
  21. 21 pre[v] = edge[i];//v所在这条边的边权
  22. 22 dis[v] = dis[u] + edge[i];
  23. 23 dfs(v, u);
  24. 24 }
  25. 25 }
  26. 26 int getlca(int x, int y) {
  27. 27 if (dep[x] < dep[y]) swap(x, y);
  28. 28 for (int i = 20; i >= 0; i --) {
  29. 29 if (dep[fa[x][i]] >= dep[y]) x = fa[x][i];
  30. 30 }
  31. 31 if (x == y) return x;
  32. 32 for (int i = 20; i >= 0; i --) {
  33. 33 if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
  34. 34 }
  35. 35 return fa[x][0];
  36. 36 }
  37. 37 int flag, cnt, maxn;
  38. 38 int judge(int u, int f, int cnt, int maxn) {//返回子树和
  39. 39 int k = num[u];
  40. 40 for (int i = head[u]; i; i = nxt[i]) {
  41. 41 int v = to[i];
  42. 42 if (v == f) continue;
  43. 43 k += judge(v, u, cnt, maxn);
  44. 44 }
  45. 45 if (k >= cnt && pre[u] >= maxn) flag = 1;
  46. 46 //所有>mid的边都经过u所在这条边i,且i的权值满足条件
  47. 47 return k;
  48. 48 }
  49. 49 bool check(ll mid) {
  50. 50 memset(num, 0, sizeof num);
  51. 51 maxn = cnt = flag = 0;
  52. 52 for (int i = 1; i <= m; i ++) {
  53. 53 int d = dis[q[i].x] + dis[q[i].y] - 2 * dis[q[i].lca];
  54. 54 if (d > mid) {
  55. 55 num[q[i].x] ++, num[q[i].y] ++, num[q[i].lca] -= 2;
  56. 56 cnt ++;
  57. 57 maxn = max(maxn, d);
  58. 58 }
  59. 59 }
  60. 60 if (!cnt) return 1; // !!!!!
  61. 61 judge(1, 0, cnt, maxn - mid);
  62. 62 return flag;
  63. 63 }
  64. 64 int main() {
  65. 65 scanf("%d %d", &n, &m);
  66. 66 for (int i = 1; i < n; i ++) {
  67. 67 int a, b, c;
  68. 68 scanf("%d %d %d", &a, &b, &c);
  69. 69 add(a, b, c), add(b, a, c);
  70. 70 }
  71. 71 dfs(1, 0);
  72. 72 for (int i = 1; i <= m; i ++) {
  73. 73 scanf("%d %d", &q[i].x, &q[i].y);
  74. 74 q[i].lca = getlca(q[i].x, q[i].y);
  75. 75 }
  76. 76 ll l = 0, r = 300000000;
  77. 77 while (l < r) {
  78. 78 ll mid = (l + r) >> 1;
  79. 79 if (check(mid)) r = mid;
  80. 80 else l = mid + 1;
  81. 81 }
  82. 82 printf("%lld\n", l);
  83. 83 return 0;
  84. 84 }

P2680 [NOIP2015 提高组] 运输计划 (树上差分-边差分)的更多相关文章

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

    链接:P2680 题意: 在树上把一条边边权变为0使得最长给定路径最短 分析: 最大值最小可以想到二分答案,对于每一个mid,寻找所有大于mid的路径,再寻找是否存在一条边使得删去它后大于mid的路径 ...

  2. NOIP2015 提高组] 运输计划

    码农题啊兄弟们. 随便考虑二分一下,然后发现要取一条满足性质的边. 被所有大于\(mid\)的路径都覆盖,取了之后能把他们都弄到小于\(mid\) 那就树上差分再处理一下. 写了\(180h\),老年 ...

  3. [NOIP2015 提高组] 运输计划题解

    题目链接:P2680 [NOIP2015 提高组] 运输计划 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 看了好长时间题解才终于懂的,有关lca和二分答案的题解解释的不详细,一时 ...

  4. [NOIP2015提高组]运输计划

    题目:BZOJ4326.洛谷P2680.Vijos P1983.UOJ#150.codevs4632.codevs5440. 题目大意:有一棵带权树,有一些运输计划,第i个运输计划从ai到bi,耗时为 ...

  5. 【数据结构】运输计划 NOIP2015提高组D2T3

    [数据结构]运输计划 NOIP2015提高组D2T3 >>>>题目 [题目描述] 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航 ...

  6. [NOIP 2015]运输计划-[树上差分+二分答案]-解题报告

    [NOIP 2015]运输计划 题面: A[NOIP2015 Day2]运输计划 时间限制 : 20000 MS 空间限制 : 262144 KB 问题描述 公元 2044 年,人类进入了宇宙纪元. ...

  7. 【题解】NOIP2015提高组 复赛

    [题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...

  8. 洛谷 P2678 & [NOIP2015提高组] 跳石头

    题目链接 https://www.luogu.org/problemnew/show/P2678 题目背景 一年一度的“跳石头”比赛又要开始了! 题目描述 这项比赛将在一条笔直的河道中进行,河道中分布 ...

  9. 【二分查找】 跳石头NOIP2015提高组 D2T1

    [二分查找]跳石头NOIP2015提高组 D2T1 >>>>题目 [题目描述] 一年一度的“跳石头”比赛又要开始了! 这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石 ...

随机推荐

  1. Netty-ProtobufVarint32

    效果 ProtobufVarint32LengthFieldPrepender编码器用于在数据最前面添加Varint32,表示数据长度 ProtobufVarint32FrameDecoder是相对应 ...

  2. Spring源码 08 IOC refresh方法3

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  3. Markdown 常用语法精讲

    - #### 标题 (`# 跟标题名称一定要留空格`)> > # 一级标题> ## 二级标题> ### 三级标题> #### 四级标题> ##### 五级标题> ...

  4. java-数组排序之冒泡排序(经典排序)

    public class BubbleSort { public static void main(String[] args) { /*冒泡排序不一定是用时最短的 * 1)声明整型数组arr,包含1 ...

  5. 聊天机器人框架Rasa资源整理

      Rasa是一个主流的构建对话机器人的开源框架,它的优点是几乎覆盖了对话系统的所有功能,并且每个模块都有很好的可扩展性.参考文献收集了一些Rasa相关的开源项目和优质文章. 一.Rasa介绍 1.R ...

  6. Linux有趣命令

    通外网 下载使用阿里云镜像源:wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.re ...

  7. TextView 中文本内容换行

    TextView 中文本内容换行 首先如图所示,我的第一栏围城的书名和书的介绍是在同一行 但是我想让书名和书的介绍分开个站一行 这时我只要在我的数组文本中的文本用 "\n" 就可以 ...

  8. C语言可以在执行语句中间定义变量吗?

    C语言可以在执行语句中间定义变量吗? 例如:for(int i=0; i<5; i++){                                                     ...

  9. 统一建模语言UML---类图

    什么是统一建模语言,来看看百科中的介绍统一建模语言(Unified Modeling Language,UML)是一种为面向对象系统的产品进行说明.可视化和编制文档的一种标准语言,是非专利的第三代建模 ...

  10. Java开发学习(三十四)----Maven私服(二)本地仓库访问私服配置与私服资源上传下载

    一.本地仓库访问私服配置 我们通过IDEA将开发的模块上传到私服,中间是要经过本地Maven的 本地Maven需要知道私服的访问地址以及私服访问的用户名和密码 私服中的仓库很多,Maven最终要把资源 ...