观察可得,$(x,y)$能相互到达当且仅当:1.$x$和$y$联通;2.$x$和$y$所在的连通块不为链
根据这个结论,可以二分枚举答案+暴力判定,复杂度$o(qm\log_{2}1e9)$,可以通过$Subtask\ 1-4$
考虑$Subtask\ 5$,即构造出一棵联通子图使得:包含$x$到$y$的链且存在度超过2的点,之后最小化边权最大值
设一个度超过2的点为$z$,贪心可以发现存在最优解为$x,y,z$联通的最小子图+与$z$相邻的3条最小的边(已经出现了就不用添加,这保证了答案合法且答案必然不小于第3小的边权)
边权是取$\max$,重复计算不影响结果,因此边权最大值为$\max(mx(x,y),mx(x,z),mn[z])$(其中$mx(x,y)$表示$x$到$y$的链上最大边,$mn[z]$表示与$z$相邻的第3小边的边权),即最小化这个式子
提出$mx(x,y)$,对后者预处理:先dp求出子树内的最小值和次小值,子树外的最小值即min(父亲,父亲子树外最小值,兄弟子树内最小值),其中兄弟子树内最小值分类讨论即可,最终复杂度为$o((q+n)\log_{2}n)$($\log$为倍增计算$mx(x,y)$)
考虑一张图,与树不同的地方有两点:
1.由于两点间路径不唯一,$mx(x,y)$的定义需要改为最大边权最小的路径
2.并不一定存在度超过2的点,但如果不存在必然整个连通块为一个环
先求出最小生成树,对于第1点,可以证明这条路径一定是最小生成树上的路径,同样被倍增计算即可
考虑第2点,与找到度大于2的点类似,必然存在一个点与非树边相连,同样记为$z$,那么只需要将$mn[z]$改为与$z$相连的最小非树边即可(最小生成树中,一个环上最大边必然为非树边)

  1. 1 #include "swap.h"
  2. 2 #include<bits/stdc++.h>
  3. 3 using namespace std;
  4. 4 #define N 100005
  5. 5 struct ji{
  6. 6 int nex,to,len;
  7. 7 }edge[N<<1];
  8. 8 pair<int,int>id[N<<1];
  9. 9 int E,n,m,head[N],r[N],mn[N],sh[N],f[N],ff[N],fo[N],fa[N][21],mx[N][21];
  10. 10 int find(int k){
  11. 11 if (k==f[k])return k;
  12. 12 return f[k]=find(f[k]);
  13. 13 }
  14. 14 void add(int x,int y,int z){
  15. 15 edge[E].nex=head[x];
  16. 16 edge[E].to=y;
  17. 17 edge[E].len=z;
  18. 18 head[x]=E++;
  19. 19 }
  20. 20 int lca(int x,int y){
  21. 21 if (sh[x]<sh[y])swap(x,y);
  22. 22 for(int i=20;i>=0;i--)
  23. 23 if (sh[fa[x][i]]>=sh[y])x=fa[x][i];
  24. 24 if (x==y)return x;
  25. 25 for(int i=20;i>=0;i--)
  26. 26 if (fa[x][i]!=fa[y][i]){
  27. 27 x=fa[x][i];
  28. 28 y=fa[y][i];
  29. 29 }
  30. 30 return fa[x][0];
  31. 31 }
  32. 32 int calc(int x,int y){
  33. 33 int ans=0;
  34. 34 for(int i=20;i>=0;i--)
  35. 35 if (sh[fa[x][i]]>=sh[y]){
  36. 36 ans=max(ans,mx[x][i]);
  37. 37 x=fa[x][i];
  38. 38 }
  39. 39 return ans;
  40. 40 }
  41. 41 void dfs(int k,int f,int s){
  42. 42 sh[k]=s;
  43. 43 fa[k][0]=f;
  44. 44 for(int i=1;i<=20;i++){
  45. 45 fa[k][i]=fa[fa[k][i-1]][i-1];
  46. 46 mx[k][i]=max(mx[k][i-1],mx[fa[k][i-1]][i-1]);
  47. 47 }
  48. 48 for(int i=head[k];i!=-1;i=edge[i].nex)
  49. 49 if (edge[i].to!=f){
  50. 50 mx[edge[i].to][0]=edge[i].len;
  51. 51 dfs(edge[i].to,k,s+1);
  52. 52 }
  53. 53 }
  54. 54 void dp1(int k,int fa){
  55. 55 f[k]=mn[k];
  56. 56 ff[k]=0x3f3f3f3f;
  57. 57 for(int i=head[k];i!=-1;i=edge[i].nex)
  58. 58 if (edge[i].to!=fa){
  59. 59 dp1(edge[i].to,k);
  60. 60 int x=max(f[edge[i].to],edge[i].len);
  61. 61 if (f[k]>x)swap(f[k],x);
  62. 62 if (ff[k]>x)swap(ff[k],x);
  63. 63 }
  64. 64 }
  65. 65 void dp2(int k,int fa){
  66. 66 if (f[fa]!=max(f[k],mx[k][0]))fo[k]=min(fo[fa],f[fa]);
  67. 67 else fo[k]=min(fo[fa],ff[fa]);
  68. 68 if (k==0)fo[k]=0x3f3f3f3f;
  69. 69 fo[k]=max(fo[k],mx[k][0]);
  70. 70 for(int i=head[k];i!=-1;i=edge[i].nex)
  71. 71 if (edge[i].to!=fa)dp2(edge[i].to,k);
  72. 72 }
  73. 73 void init(int nn,int mm,vector<int>u,vector<int>v,vector<int>w){
  74. 74 n=nn;
  75. 75 m=mm;
  76. 76 for(int i=0;i<m;i++)id[i]=make_pair(w[i],i);
  77. 77 sort(id,id+m);
  78. 78 E=0;
  79. 79 memset(head,-1,sizeof(head));
  80. 80 memset(mn,0x3f,sizeof(mn));
  81. 81 for(int i=0;i<n;i++)f[i]=i;
  82. 82 for(int i=0;i<m;i++){
  83. 83 int k=id[i].second,x=find(u[k]),y=find(v[k]);
  84. 84 if ((x==y)||(++r[u[k]]==3))mn[u[k]]=min(mn[u[k]],w[k]);
  85. 85 if ((x==y)||(++r[v[k]]==3))mn[v[k]]=min(mn[v[k]],w[k]);
  86. 86 if (x!=y){
  87. 87 f[x]=y;
  88. 88 add(u[k],v[k],w[k]);
  89. 89 add(v[k],u[k],w[k]);
  90. 90 }
  91. 91 }
  92. 92 dfs(0,0,0);
  93. 93 dp1(0,0);
  94. 94 dp2(0,0);
  95. 95 }
  96. 96 int getMinimumFuelCapacity(int x,int y){
  97. 97 int z=lca(x,y),ans=max(max(calc(x,z),calc(y,z)),min(f[x],fo[x]));
  98. 98 if (ans==0x3f3f3f3f)ans=-1;
  99. 99 return ans;
  100. 100 }

[loj3346]交换城市的更多相关文章

  1. 【APIO2020】交换城市(Kruskal重构树)

    Description 给定一个 \(n\) 个点,\(m\) 条边的无向连通图,边带权. \(q\) 次询问,每次询问两个点 \(x, y\),求两点间的次小瓶颈路.不存在输出 -1. Hint \ ...

  2. APIO2020 交换城市

    我是真的不稳定的垃圾选手. 对于一张图来说,两个人能满足题面关系等价于这张图不是链,很好证明,如果有度数 \(> 2\) 的点,让一个人跑到一个度数 \(= 1\) 的地方就可以了. 如果离线就 ...

  3. 微信小程序开发心得

    微信小程序也已出来有一段时间了,最近写了几款微信小程序项目,今天来说说感受. 首先开发一款微信小程序,最主要的就是针对于公司来运营的,因为,在申请appid(微信小程序ID号)时候,需要填写相关的公司 ...

  4. 微信小程序开发心得--动画机制

    微信小程序也已出来有一段时间了,最近写了几款微信小程序项目,今天来说说感受.首先开发一款微信小程序,最主要的就是针对于公司来运营的,因为,在申请appid(微信小程序ID号)时候,需要填写相关的公司认 ...

  5. 城市经纬度 json 理解SignalR Main(string[] args)之args传递的几种方式 串口编程之端口 多线程详细介绍 递归一个List<T>,可自己根据需要改造为通用型。 Sql 优化解决方案

    城市经纬度 json https://www.cnblogs.com/innershare/p/10723968.html 理解SignalR ASP .NET SignalR 是一个ASP .NET ...

  6. 移动GIS技术在城市信息采集中的应用

    1 引言 随着移动平板电脑和手机(以下简称移动终端)在软硬件上的更新换代,和3G.4G通讯网络的升级,传统测绘和和数据服务方式正在发生巨大变化.以城市中的外业踏勘和信息采集为例,移动终端正成为主要的外 ...

  7. 【BZOJ3091】城市旅行 LCT

    [BZOJ3091]城市旅行 Description Input Output Sample Input 4 5 1 3 2 5 1 2 1 3 2 4 4 2 4 1 2 4 2 3 4 3 1 4 ...

  8. “智慧海绵城市”(SSC)监测评价体系整体解决方案

    一.方案简介 无论是内涝防治.黑臭水体治理,还是海绵城市规划设计及建设.评估,乃至未来智慧城市的建设,都需要有全面.致密.大量的城市水文监测数据和先进模拟仿真技术作基础支撑,唯有如此,决策才有据可依, ...

  9. BIM与GIS融合的意义——从智慧工地到智慧城市

    随着智慧城市概念的发展,BIM与GIS融合的概念深入人心,通过整合BIM的参数化描述建筑组件性质的特性与GIS宏观的几何空间概念,将 BIM 描述单体建筑物的特性通过 GIS 拓展至三维城市. BIM ...

随机推荐

  1. 洛谷4234最小差值生成树 (LCT维护生成树)

    这也是一道LCT维护生成树的题. 那么我们还是按照套路,先对边进行排序,然后顺次加入. 不过和别的题有所不同的是: 在本题中,我们需要保证LCT中正好有\(n-1\)条边的时候,才能更新\(ans\) ...

  2. 【java】关键字this怎么用?

    摘至:https://www.php.cn/java/guide/462643.html java中this关键字的用法:1.当成员变量和局部变量重名时,在方法中使用this时,表示的是该方法所在类中 ...

  3. C#与java TCP通道加密通信

    背景说明 公司收费系统需要与银行做实时代收对接,业务协议使用我们收费系统的标准.但是银行要求在业务协议的基础上,使用银行的加密规则. 采用MD5计算报文摘要,保证数据的完整性 采用RSA256对摘要进 ...

  4. noj->电子老鼠走迷宫

    00 问题 描述: 有一只电子老鼠被困在如下图所示的迷宫中.这是一个12*12单元的正方形迷宫,黑色部分表示建筑物,白色部分是路.电子老鼠可以在路上向上.下.左.右行走,每一步走一个格子.现给定一个起 ...

  5. 浅析ReDoS的原理与实践

    转载于http://www.freebuf.com/articles/network/124422.html ReDoS(Regular expression Denial of Service) 正 ...

  6. UltraSoft - Beta - Scrum Meeting 2

    Date: May 18th, 2020. Scrum 情况汇报 进度情况 组员 负责 今日进度 q2l PM.后端 建立Beta仓库管理增加服务器部署和Git协作文档 Liuzh 前端 查阅响应式布 ...

  7. Django+Vue跨域配置与经验

    一.原理 同源?同源策略? 同源的定义是:两个页面的协议.端口和域名都相同 同源的例子: 不同源的例子: 同源策略SOP(Same origin policy)是一种浏览器约定,它是浏览器最核心也最基 ...

  8. 【技术博客】利用handler实现线程之间的消息传递

    [技术博客]利用handler实现线程之间的消息传递 一.handler简介 在Android Studio的开发中,经常需要启动多个线程.比如向远程发送请求时,必须新开一个子线程,否则会造成程序崩溃 ...

  9. Noip模拟44 2021.8.19

    比较惊人的排行榜 更不用说爆零的人数了,为什么联赛会这么难!!害怕了 还要再努力鸭 T1 Emotional Flutter 考场上没切掉的神仙题 考率如何贪心,我们把黑色的条延长$s$,白色的缩短$ ...

  10. 『学了就忘』Linux基础 — 4、VMware安装

    目录 1.VMware介绍 2.VMware主要特点 3.VMware建议配置 4.VMware安装 1.VMware介绍 VMware是一个虚拟PC的软件,可以在现有的操作系统上虚拟出一个新的硬件环 ...