P2680 运输计划

题目背景

公元2044年,人类进入了宇宙纪元。

题目描述

公元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\)的物流公司完成阶段性工作所需要的最短时间是多少?

输入输出格式

输入格式:

第一行包括两个正整数\(n, m\),表示\(L\)国中星球的数量及小\(P\)公司预接的运输计划的数量,星球从1到\(n\)编号。

接下来\(n-1\)行描述航道的建设情况,其中第\(i\)行包含三个整数\(a_i, b_i\)和\(t_i\)t ,表示第\(i\)条双向航道修建在\(a_i\)与 \(b_i\)两个星球之间,任意飞船驶过它所花费的时间为 \(t_i\) 。数据保证\(1≤a _i ,b_i ≤n\)且\(0≤t_i≤1000\)。

接下来\(m\)行描述运输计划的情况,其中第\(j\)行包含两个正整数\(u_j\)和\(v_j\) ,表示第\(j\)个运输计划是从\(u_j\)号星球飞往\(v_j\)号星球。数据保证\(1≤u_i,v_i≤n\)

输出格式:

一个整数,表示小\(P\)的物流公司完成阶段性工作所需要的最短时间。

说明:


首先简化一下问题模型:对于询问的m条链中,删去一条边,使最大链最小

妥妥的二分答案了,但是我做的时候并没有想简化模型,自然也没有想到二分答案,只是想到了贪心倍增的做法但是太难写,我估计写不出来。

下面说说二分答案。我们二分最大链长\(l\)。

对于链长小于等于\(l\)的,我们不管它。

对于链长大于\(l\)的,我们得确保删去的那条边在每条这样的链上,换而言之,我们要统计当前每条边的经历的链数。

我们找到合法的最大边,看看减去它后是否能使所有链长小于\(l\)。

那么现在还有两个问题,如何找到链如何统计每条边经历的链数

找到链即先预处理每条链的最近公共祖先,存储为三元组并带上链长。可以用\(tarjan\)直接\(O(n)\)离线处理了

统计链数时,我们发现也是离线操作而且没有修改。直接树上差分即可。

树上差分:思想与链上差分差不多,对三元组\((f,v1,v2)\)(\(f\)是后面两个祖先),维护\(f\)的差分数组减去2,\(v1,v2\)的加上1。自下往上统计前缀和即是边的经历次数。


code:

  1. #include <cstdio>
  2. #include <cstring>
  3. int max(int x,int y){return x>y?x:y;}
  4. const int N=300010;
  5. int n,m;
  6. int read()
  7. {
  8. char c=getchar();int x=0;
  9. while(c<'0'||c>'9') c=getchar();
  10. while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
  11. return x;
  12. }
  13. struct Edge{int to,next,w;}edge[N<<1];
  14. struct node{int to,next;}lca[N<<1];
  15. int head[N],cnt=0,headl[N],cntl=0,dis[N],used[N],f[N],l=0,r=0;
  16. void add(int u,int v,int w){edge[++cnt].next=head[u];edge[cnt].to=v;edge[cnt].w=w;head[u]=cnt;}
  17. void addl(int u,int v){lca[++cntl].next=headl[u];lca[cntl].to=v;headl[u]=cntl;}
  18. void dfs(int now)
  19. {
  20. used[now]=1;
  21. for(int i=head[now];i;i=edge[i].next)
  22. {
  23. int v=edge[i].to,w=edge[i].w;
  24. if(!used[v])
  25. {
  26. dis[v]=dis[now]+w;
  27. dfs(v);
  28. }
  29. }
  30. }
  31. int find(int x){return f[x]=f[x]==x?x:find(f[x]);}
  32. void merge(int x,int y){f[find(y)]=find(x);}
  33. struct lc{int v[2],w,next;}d[N];int headlc[N],cntlc=0;
  34. void addlc(int u,int w,int v1,int v2){d[++cntlc].w=w;d[cntlc].v[0]=v1;d[cntlc].v[1]=v2;d[cntlc].next=headlc[u];headlc[u]=cntlc;}
  35. void LCA(int now)
  36. {
  37. used[now]=1;
  38. for(int i=head[now];i;i=edge[i].next)
  39. {
  40. int v=edge[i].to;
  41. if(!used[v])
  42. {
  43. used[v]=1;
  44. LCA(v);
  45. merge(now,v);
  46. }
  47. }
  48. for(int i=headl[now];i;i=lca[i].next)
  49. {
  50. int v=lca[i].to;
  51. if(used[v])
  52. {
  53. int f0=find(v);
  54. int w=dis[v]-dis[f0]+dis[now]-dis[f0];
  55. r=max(r,w);
  56. addlc(f0,w,v,now);
  57. }
  58. }
  59. }
  60. void init()
  61. {
  62. dfs(1);//预处理两点间长度
  63. int a,b;
  64. for(int i=1;i<=m;i++)
  65. {
  66. a=read(),b=read();
  67. addl(a,b);
  68. addl(b,a);
  69. }
  70. memset(used,0,sizeof(used));
  71. for(int i=1;i<=n;i++) f[i]=i;
  72. LCA(1);//两点间距离及最近公共祖先
  73. }
  74. int p_d[N],cntline=0,sum[N],m_max=0,m_maxl=0;
  75. void dfs0(int now,int dist)
  76. {
  77. used[now]=1;
  78. for(int i=head[now];i;i=edge[i].next)
  79. {
  80. int v=edge[i].to,w=edge[i].w;
  81. if(!used[v])
  82. {
  83. dfs0(v,w);
  84. sum[now]+=sum[v];
  85. }
  86. }
  87. sum[now]+=p_d[now];
  88. if(sum[now]==cntline)
  89. m_max=max(m_max,dist);
  90. }
  91. bool check(int c)
  92. {
  93. memset(p_d,0,sizeof(p_d));
  94. cntline=0,m_max=0,m_maxl=0;
  95. for(int i=1;i<=n;i++)
  96. for(int j=headlc[i];j;j=d[j].next)
  97. if(d[j].w>c)
  98. {
  99. p_d[i]-=2;
  100. p_d[d[j].v[0]]++;
  101. p_d[d[j].v[1]]++;
  102. m_maxl=max(m_maxl,d[j].w);
  103. cntline++;
  104. }
  105. memset(used,0,sizeof(used));
  106. memset(sum,0,sizeof(sum));
  107. dfs0(1,0);
  108. return m_max+c>=m_maxl;
  109. }
  110. int main()
  111. {
  112. n=read(),m=read();
  113. int u,v,w;
  114. for(int i=1;i<n;i++)
  115. {
  116. u=read(),v=read(),w=read();
  117. l=max(l,w);
  118. add(u,v,w);
  119. add(v,u,w);
  120. }
  121. l=r-l;
  122. init();
  123. while(l<r)
  124. {
  125. int mid=l+r>>1;
  126. if(check(mid))
  127. r=mid;
  128. else
  129. l=mid+1;
  130. }
  131. printf("%d\n",l);
  132. return 0;
  133. }

其实这个代码\(N\)改成450,000再吸一波氧才能过。但我始终没弄清楚到底\(N\)开300,000到底是哪里\(RE\)了,有哪位大哥发现了评论一下呗~

2018.6.7

洛谷 P2680 运输计划 解题报告的更多相关文章

  1. 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)

    P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...

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

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

  3. 洛谷P2680 运输计划 [LCA,树上差分,二分答案]

    题目传送门 运输计划 Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n?1 条双向航道,每条航道建立在两个星球之间, 这 n?1 条航道连通了 L 国的所 ...

  4. 洛谷 P2680 运输计划(NOIP2015提高组)(BZOJ4326)

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

  5. 洛谷 P2680 运输计划

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

  6. 洛谷——P2680 运输计划

    https://www.luogu.org/problem/show?pid=2680 题目背景 公元 2044 年,人类进入了宇宙纪元. 题目描述 L 国有 n 个星球,还有 n-1 条双向航道,每 ...

  7. 洛谷P2680 运输计划——树上差分

    题目:https://www.luogu.org/problemnew/show/P2680 久违地1A了好高兴啊! 首先,要最大值最小,很容易想到二分: 判断当前的 mid 是否可行,需要看看有没有 ...

  8. 洛谷P2680 运输计划

    大概就是二分+树上差分... 题意:给你树上m条路径,你要把一条边权变为0,使最长的路径最短. 最大的最小,看出二分(事实上我并没有看出来...) 然后二分k,对于所有大于k的边,树上差分求出最长公共 ...

  9. 洛谷P2680运输计划

    传送门啦 要求的就是,把树上的一条边的权值设为0之后,所有路径中的最大值的最小值. 首先二分最大值,假设某次二分的最大值为x,我们首先找出所有大于x的路径(也就是我们需要通过改权缩短的路径),并把路径 ...

随机推荐

  1. 反射反射,程序员的快乐+反射案例:打印和Excel导出

    还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 看过设计模式的童鞋都知道:反射反射,程序员的快乐!今天我们就利用反射来制作打印 ...

  2. html table隐藏列

    隐藏table表的第一列,适合显示信息,隐藏ID主键. <html> <head> <meta http-equiv="content-type" c ...

  3. Dell BOSS 卡是什么

    全名: Boot Optimized Storage Solution 针对 M.2 接口的 SSD,主板上必须设计接口进行适配. 设计一款主板对于硬件厂商来说是有成本的,其中包括 主板设计成本 产品 ...

  4. 安装Visual Studio开发平台

    1.找一个VS2013的安装包,下载到D盘上,勾选相应的选项安装. 安装的过程很漫长,至少需要一个小时. 2.安装已完成,启动. . 3.登录. \ 4启动VS2013. 5.新建c#类库 6.输入代 ...

  5. 2丶利用NABCD模型进行竞争性需求分析

    确定项目:公交查询系统 分析小组:在路上 选择比努力更重要.一个项目成功自然离不开组员们的努力.但是,光努力是不够的.还需要用户有需求,能快速实现. 这些东西,看似很虚,却能让我们少走不少弯路.做项目 ...

  6. "一个程序员的生命周期"读后感

    这篇文章中作者叙述了自己和大多数大学生或许都会面对的问题,即是会走过挺多的歪路,面临很多的困难和压力,但是作者却从未放弃自己真正追求的东西.对于一个过来人的经验之谈,我们应该吸取经验,在大学好好去奋斗 ...

  7. asp.net webform设计思路的思考

    我使用asp.net的webform框架进行web应用程序的开发已经差不多四年了,在整个开发生涯中,也使用过一年asp.net的mvc框架.因为网上经常有讨论webform框架和mvc框架的优劣,所以 ...

  8. Tomcat & Servlet

    javaWeb javaWeb是指使用java技术实现所有web程序的技术的总称.我们称之为javaWeb. 1.请求和响应(成对出现) 2.Web资源的分类 web资源分为两大类,分别是静态资源和动 ...

  9. Running kubernetes on windows

    docker-for-desktop minikube GKE cluster(?) docker-for-desktop https://docs.docker.com/docker-for-win ...

  10. [转帖]从 2G 到 5G,手机上网话语权的三次改变

    从 2G 到 5G,手机上网话语权的三次改变 美国第一大电信运营商 Verizon 公司的 CEO Hans Vestberg 手持一部 iPad,屏幕上显示俯瞰地面的飞行地图.400 多公里外的洛杉 ...