[NOIP2015]运输计划

链接

luogu

好久没写博客了,水一篇波。

思路1 暴力数据结构

枚举最长链的边,删除后代价为(最长链-边权,不经过这条边的链)的最大值。

不经过某条边的最大值要用线段树维护补集。

复杂度\(O(nlog^2n)\)

思路2 二分树上差分

二分答案,删除的边为\(>mid\)的链的交集。

用树上查分维护交集。

最后在交集中找个最大的边删除就好了。

复杂度\(O(nlogn)\)

总的

思路2,复杂度小,好写,简单,细节少。

思路1,复杂度高,码量大,细节多,并不是呢么好想。

所以并不是很建议写第一种。

但他靠着树剖的小常数跑过了树上差分(至少我是这样,1.9s->1.2s)。

代码1

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int _=5e5+7;
  4. int read() {
  5. int x=0,f=1;char s=getchar();
  6. for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
  7. for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
  8. return x*f;
  9. }
  10. int n,m,ans,u[_],v[_],dsr[_],w[_];
  11. struct node {
  12. int v,nxt,q,w;
  13. }e[_<<1];
  14. int head[_],tot;
  15. void add(int u,int v,int q) {
  16. e[++tot].v=v;
  17. e[tot].q=q;
  18. e[tot].nxt=head[u];
  19. head[u]=tot;
  20. }
  21. int f[_],dep[_],siz[_],son[_],top[_],idx[_],dis[_],nb[_],cnt;
  22. void dfs1(int u,int fa) {
  23. dep[u]=dep[fa]+1;
  24. f[u]=fa;
  25. siz[u]=1;
  26. for(int i=head[u];i;i=e[i].nxt) {
  27. int v=e[i].v;
  28. if(v==fa) continue;
  29. w[v]=e[i].q;
  30. dis[v]=dis[u]+e[i].q;
  31. dfs1(v,u);
  32. siz[u]+=siz[v];
  33. if(siz[son[u]]<siz[v]) son[u]=v;
  34. }
  35. }
  36. void dfs2(int u,int topf) {
  37. top[u]=topf;
  38. idx[u]=++cnt;
  39. nb[cnt]=u;
  40. if(!son[u]) return;
  41. dfs2(son[u],topf);
  42. for(int i=head[u];i;i=e[i].nxt) {
  43. int v=e[i].v;
  44. if(!idx[v]) dfs2(v,v);
  45. }
  46. }
  47. namespace seg_tree {
  48. #define ls rt<<1
  49. #define rs rt<<1|1
  50. int ma[_<<2],lazy[_];
  51. void tag(int rt,int val) {ma[rt]=max(ma[rt],val);lazy[rt]=max(lazy[rt],val);}
  52. void pushdown(int rt) {tag(ls,lazy[rt]);tag(rs,lazy[rt]);}
  53. void modify(int L,int R,int val,int l,int r,int rt) {
  54. if(L>R) return;
  55. if(L<=l&&r<=R) return tag(rt,val);
  56. int mid=(l+r)>>1;
  57. pushdown(rt);
  58. if(L<=mid) modify(L,R,val,l,mid,ls);
  59. if(R>mid) modify(L,R,val,mid+1,r,rs);
  60. ma[rt]=max(ma[ls],ma[rs]);
  61. }
  62. void dfs(int l,int r,int rt) {
  63. if(l==r) return void(dsr[nb[l]]=ma[rt]);
  64. int mid=(l+r)>>1;
  65. pushdown(rt);
  66. if(l<=mid) dfs(l,mid,ls);
  67. if(r>mid) dfs(mid+1,r,rs);
  68. }
  69. }
  70. int lca(int x,int y) {
  71. while(top[x]!=top[y]) {
  72. if(dep[top[x]]<dep[top[y]]) swap(x,y);
  73. x=f[top[x]];
  74. } return dep[x]<dep[y]?x:y;
  75. }
  76. void QQ(int x,int y,int val) {
  77. int las=n;
  78. while(top[x]!=top[y]) {
  79. if(dep[top[x]]<dep[top[y]]) swap(x,y);
  80. seg_tree::modify(idx[x]+1,las,val,1,n,1);
  81. las=idx[top[x]]-1;
  82. x=f[top[x]];
  83. }
  84. if(dep[x]<dep[y]) swap(x,y);
  85. seg_tree::modify(idx[x]+1,las,val,1,n,1);
  86. seg_tree::modify(1,idx[y],val,1,n,1);
  87. }
  88. int main() {
  89. n=read(),m=read();
  90. for(int i=1,x,y,q;i<n;++i) {
  91. x=read(),y=read(),q=read();
  92. add(x,y,q),add(y,x,q);
  93. }
  94. for(int i=1;i<=m;++i) {
  95. u[i]=read(),v[i]=read();
  96. if(u[i]==v[i]) m--,i--;
  97. }
  98. dfs1(1,0),dfs2(1,1);
  99. int id=0,ma=0;
  100. for(int i=1;i<=m;++i) {
  101. int val=dis[u[i]]+dis[v[i]]-2*dis[lca(u[i],v[i])];
  102. QQ(u[i],v[i],val);
  103. if(ma<val) id=i,ma=val;
  104. }
  105. if(!id) return printf("0\n"),0;
  106. seg_tree::dfs(1,n,1);
  107. int x=u[id],y=v[id],ans=0x3f3f3f3f;
  108. while(x!=y) {
  109. if(dep[x]<dep[y]) swap(x,y);
  110. ans=min(ans,max(dsr[x],ma-w[x]));
  111. x=f[x];
  112. }
  113. cout<<ans<<"\n";
  114. return 0;
  115. }

代码2

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int _=5e5+7;
  4. int read() {
  5. int x=0,f=1;char s=getchar();
  6. for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
  7. for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
  8. return x*f;
  9. }
  10. int n,m,ans,u[_],v[_],LCA[_],len[_],the_biggest,w[_];
  11. struct node {
  12. int v,nxt,q;
  13. }e[_<<1];
  14. int head[_],tot;
  15. void add(int u,int v,int q) {
  16. e[++tot].v=v;
  17. e[tot].q=q;
  18. e[tot].nxt=head[u];
  19. head[u]=tot;
  20. }
  21. int f[_],dep[_],siz[_],son[_],dis[_],top[_],cnt;
  22. void dfs1(int u,int fa) {
  23. dep[u]=dep[fa]+1,f[u]=fa,siz[u]=1;
  24. for(int i=head[u];i;i=e[i].nxt) {
  25. int v=e[i].v;
  26. if(v==fa) continue;
  27. w[v]=e[i].q;
  28. dis[v]=dis[u]+e[i].q;
  29. dfs1(v,u);
  30. siz[u]+=siz[v];
  31. if(siz[son[u]]<siz[v]) son[u]=v;
  32. }
  33. }
  34. void dfs2(int u,int topf) {
  35. top[u]=topf;
  36. if(!son[u]) return;
  37. dfs2(son[u],topf);
  38. for(int i=head[u];i;i=e[i].nxt) {
  39. int v=e[i].v;
  40. if(!top[v]) dfs2(v,v);
  41. }
  42. }
  43. int lca(int x,int y) {
  44. while(top[x]!=top[y]) {
  45. if(dep[top[x]]<dep[top[y]]) swap(x,y);
  46. x=f[top[x]];
  47. } return dep[x]<dep[y]?x:y;
  48. }
  49. int dsr[_],js;
  50. void dfs(int u,int fa) {
  51. for(int i=head[u];i;i=e[i].nxt) {
  52. int v=e[i].v;
  53. if(v==fa) continue;
  54. dfs(v,u);
  55. dsr[u]+=dsr[v];
  56. }
  57. }
  58. bool check(int mid) {
  59. js=0;
  60. for(int i=0;i<=n;++i) dsr[i]=0;
  61. for(int i=1;i<=m;++i) {
  62. if(len[i]<=mid) continue;
  63. dsr[LCA[i]]-=2;
  64. dsr[u[i]]++;
  65. dsr[v[i]]++;
  66. ++js;
  67. }
  68. dfs(1,0);
  69. int ma=0x3f3f3f3f;
  70. for(int i=1;i<=n;++i)
  71. if(dsr[i]==js) ma=min(ma,the_biggest-w[i]);
  72. return ma<=mid;
  73. }
  74. int main() {
  75. n=read(),m=read();
  76. for(int i=1,x,y,q;i<n;++i) {
  77. x=read(),y=read(),q=read();
  78. add(x,y,q),add(y,x,q);
  79. }
  80. dfs1(1,0),dfs2(1,1);
  81. for(int i=1;i<=m;++i) {
  82. u[i]=read(),v[i]=read(),LCA[i]=lca(u[i],v[i]);
  83. len[i]=dis[u[i]]+dis[v[i]]-2*dis[LCA[i]];
  84. the_biggest=max(the_biggest,len[i]);
  85. }
  86. int l=0,r=the_biggest,ans=0;
  87. while(l<=r) {
  88. int mid=(l+r)>>1;
  89. if(check(mid)) ans=mid,r=mid-1;
  90. else l=mid+1;
  91. } cout<<ans<<"\n";
  92. return 0;
  93. }

[NOIP2015]运输计划 线段树or差分二分的更多相关文章

  1. bzoj 4326: NOIP2015 运输计划【树链剖分+二分+树上差分】

    常数巨大,lg上开o2才能A 首先预处理出运输计划的长度len和lca,然后二分一个长度w,对于长度大于w的运输计划,在树上差分(d[u]+1,d[v]+1,d[lca]-2),然后dfs,找出所有覆 ...

  2. 洛谷P2680 运输计划(倍增LCA + 树上差分 + 二分答案)

    [题目链接] [思路]: 根据题意可以明显看出,当所有任务都完成时的时间是最终的结果,也就是说本题要求,求出最小的最大值. 那这样的话就暗示了将答案二分,进行check. [check方法]: 如果说 ...

  3. [NOIP2015]运输计划 D2 T3 LCA+二分答案+差分数组

    [NOIP2015]运输计划 D2 T3 Description 公元2044年,人类进入了宇宙纪元. L国有n个星球,还有n-1条双向航道,每条航道建立在两个星球之间,这n-1条航道连通了L国的所有 ...

  4. BZOJ 4326:NOIP2015 运输计划(二分+差分+lca)

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

  5. NOIP2015 运输计划(二分+LCA+差分)

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

  6. Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分)

    Luogu 2680 NOIP 2015 运输计划(树链剖分,LCA,树状数组,树的重心,二分,差分) Description L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之 ...

  7. BZOJ 4326 NOIP2015 运输计划 (二分+树上差分)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1930  Solved: 1231[Submit][Statu ...

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

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

  9. BZOJ 4326 NOIP2015 运输计划(树上差分+LCA+二分答案)

    4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MB Submit: 1388  Solved: 860 [Submit][Stat ...

随机推荐

  1. SEO-------- 了解

    SEO(Search Engine Optimization) 译为:搜索引擎优化,是一种透过了解搜索引擎的运作规则来调整网站,以及提高目的的网站在有关搜索引擎内的排名方式. 目的:为了让用户更快的搜 ...

  2. Springboot如何打包部署项目

    原文地址 目录 前言 1. 导入插件 2.idea中快速打包 3.java –jar运行项目 4.访问项目 5.发布到服务器 前言 用心写好每一篇文章,真心对待每一个读者 文章首发地址: www.ja ...

  3. CodeForce 192D Demonstration

    In the capital city of Berland, Bertown, demonstrations are against the recent election of the King ...

  4. bootstrap中的col-md-*

    一句话概括,就是根据显示屏幕宽度的大小,自动的选用对应的类的样式 1.col是column简写:列 2.xs是maxsmall简写:超小, sm是small简写:小,  md是medium简写:中等, ...

  5. mysql启动报错:Failed to start LSB: start and stop MySQL

    报错信息: [root@youxx- bin]# service mysql status Redirecting to /bin/systemctl status mysql.service ¡ñ ...

  6. 微软开放了.NET 4.5.1的源代码【转】

    .NET Reference Source发布了beta版,可以在线浏览.NET Framework 4.5.1的源代码,并且可以通过配置,在Visual Studio 2013中调试.NET Fra ...

  7. Kubernetes 动态PV使用

    Kubernetes 动态PV使用 Kubernetes支持动态供给的存储插件:https://kubernetes.io/docs/concepts/storage/storage-classes/ ...

  8. SpringBoot多数据源动态切换数据源

    1.配置多数据源 spring: datasource: master: password: erp_test@abc url: jdbc:mysql://127.0.0.1:3306/M201911 ...

  9. C#使用SharpZipLib创建压缩文件,并指定压缩文件夹路径(解决SharpZipLib压缩长路径显示问题)

    在项目中使用SharpZipLib压缩文件夹的时候,遇到如果目录较深,则压缩包中的文件夹同样比较深的问题.比如,压缩当前程序目录下的某个文件夹(D:\cx\code\program\bin\debug ...

  10. c# 调用接口返回json

    需要命名空间 using System.Net; using System.Net.Security using System.Security.Cryptography.X509Certificat ...