题意

​ 给定一张 \(n\) 个点 \(m\) 条边的无向图,\(q\) 次询问,每次询问两边之间的必经之点个数。

思路

​ 求两点之间必经之边的个数用的是边双缩点,再求树上距离。而对比边双和点双之后,我们不难发现点和边之间的对应关系,边双分量和点双分量的性质很多都是对称的。

边双 点双
两点之间至少有两条不共边的路径 两边之间至少有两条不共点的路径
边双间由桥边连接 点双内没有割点
边双间由桥边连接 点双间由割点连接

​ 另外,一个点双也是一个特殊的边双,就像一个点仙人掌是一个特殊的边仙人掌一样。

​ 那就容易看出本题就是一个点双缩点的裸题了。把所有的割点和点双分量拿出来,让每一个割点向它所在的点双分量连边即可。可能把图“缩成树”这种事本来就适合边双干,点双写起来不是很自然,也没什么办法。

代码

  1. #include<bits/stdc++.h>
  2. #define FOR(i, x, y) for(int i = (x), i##END = (y); i <= i##END; ++i)
  3. #define DOR(i, x, y) for(int i = (x), i##END = (y); i >= i##END; --i)
  4. template<typename T, typename _T> inline bool chk_min(T &x, const _T &y) {return y < x ? x = y, 1 : 0;}
  5. template<typename T, typename _T> inline bool chk_max(T &x, const _T &y) {return x < y ? x = y, 1 : 0;}
  6. typedef long long ll;
  7. const int N = 10005;
  8. const int M = 100005;
  9. template<const int N, const int M, typename T> struct Linked_List
  10. {
  11. int head[N], nxt[M], tot; T to[M];
  12. Linked_List() {clear();}
  13. T &operator [](const int x) {return to[x];}
  14. void clear() {memset(head, -1, sizeof(head)), tot = 0;}
  15. void add(int u, T v) {to[tot] = v, nxt[tot] = head[u], head[u] = tot++;}
  16. #define EOR(i, G, u) for(int i = G.head[u]; ~i; i = G.nxt[i])
  17. };
  18. Linked_List<N, M << 1, int> G;
  19. Linked_List<N << 1, N << 2, int> T;
  20. int dfn[N], low[N], stk[M], bel[M], dfn_idx, bcc, tp, tot;
  21. bool mark[M];
  22. int fa[N << 1], dep[N << 1], sz[N << 1], son[N << 1], top[N << 1];
  23. int n, m, q;
  24. void tarjan(int u, int fa_e)
  25. {
  26. dfn[u] = low[u] = ++dfn_idx;
  27. EOR(i, G, u)
  28. {
  29. if(i == (fa_e ^ 1)) continue;
  30. int v = G[i];
  31. if(!dfn[v])
  32. {
  33. stk[++tp] = i;
  34. tarjan(v, i), chk_min(low[u], low[v]);
  35. if(low[v] >= dfn[u])
  36. {
  37. bcc++;
  38. do bel[stk[tp] / 2] = bcc;
  39. while(stk[tp--] != i);
  40. }
  41. }
  42. else if(dfn[v] < dfn[u])
  43. {
  44. stk[++tp] = i;
  45. chk_min(low[u], dfn[v]);
  46. }
  47. }
  48. }
  49. void dfs(int u, int f, int d)
  50. {
  51. fa[u] = f, dep[u] = d, sz[u] = 1, son[u] = 0;
  52. EOR(i, T, u)
  53. {
  54. int v = T[i];
  55. if(v == f) continue;
  56. dfs(v, u, d + 1);
  57. sz[u] += sz[v];
  58. if(sz[v] > sz[son[u]]) son[u] = v;
  59. }
  60. }
  61. void hld(int u, int tp)
  62. {
  63. top[u] = tp;
  64. if(son[u]) hld(son[u], tp);
  65. EOR(i, T, u)
  66. {
  67. int v = T[i];
  68. if(v == fa[u] || v == son[u]) continue;
  69. hld(v, v);
  70. }
  71. }
  72. int get_lca(int u, int v)
  73. {
  74. while(top[u] != top[v])
  75. {
  76. if(dep[top[u]] < dep[top[v]]) std::swap(u, v);
  77. u = fa[top[u]];
  78. }
  79. return dep[u] < dep[v] ? u : v;
  80. }
  81. int get_dis(int u, int v)
  82. {
  83. int lca = get_lca(u, v);
  84. return dep[u] + dep[v] - 2 * dep[lca];
  85. }
  86. int main()
  87. {
  88. while(scanf("%d%d", &n, &m), (n || m))
  89. {
  90. G.tot = T.tot = 0;
  91. FOR(i, 1, n) G.head[i] = -1, dfn[i] = 0;
  92. FOR(i, 1, 2 * n) T.head[i] = -1, dep[i] = 0;
  93. bcc = dfn_idx = tp = 0;
  94. FOR(i, 1, m)
  95. {
  96. int u, v;
  97. scanf("%d%d", &u, &v);
  98. G.add(u, v), G.add(v, u);
  99. }
  100. FOR(i, 1, n) if(!dfn[i]) tarjan(i, -1);
  101. tot = bcc;
  102. FOR(u, 1, n)
  103. {
  104. tp = 0;
  105. EOR(i, G, u)
  106. {
  107. if(!mark[bel[i / 2]])
  108. {
  109. mark[bel[i / 2]] = 1;
  110. stk[++tp] = bel[i / 2];
  111. }
  112. }
  113. if(tp >= 2)
  114. {
  115. tot++;
  116. FOR(i, 1, tp) T.add(tot, stk[i]), T.add(stk[i], tot);
  117. }
  118. while(tp) mark[stk[tp]] = 0, tp--;
  119. }
  120. FOR(i, 1, tot) if(!dep[i]) dfs(i, 0, 1), hld(i, i);
  121. scanf("%d", &q);
  122. while(q--)
  123. {
  124. int e1, e2;
  125. scanf("%d%d", &e1, &e2);
  126. e1--, e2--;
  127. printf("%d\n", get_dis(bel[e1], bel[e2]) / 2);
  128. }
  129. }
  130. return 0;
  131. }

HDU 3686 Traffic Real Time Query System(点双连通)的更多相关文章

  1. HDU 3686 Traffic Real Time Query System(双连通分量缩点+LCA)(2010 Asia Hangzhou Regional Contest)

    Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...

  2. hdu 3686 Traffic Real Time Query System 点双两通分量 + LCA。这题有重边!!!

    http://acm.hdu.edu.cn/showproblem.php?pid=3686 我要把这题记录下来. 一直wa. 自己生成数据都是AC的.现在还是wa.留坑. 我感觉我现在倒下去床上就能 ...

  3. HDU 3686 Traffic Real Time Query System (图论)

    HDU 3686 Traffic Real Time Query System 题目大意 给一个N个点M条边的无向图,然后有Q个询问X,Y,问第X边到第Y边必需要经过的点有多少个. solution ...

  4. 【HDOJ】3686 Traffic Real Time Query System

    这题做了几个小时,基本思路肯定是求两点路径中的割点数目,思路是tarjan缩点,然后以割点和连通块作为新节点见图.转化为lca求解.结合点——双连通分量与LCA. /* 3686 */ #includ ...

  5. 【Targan+LCA】HDU 3686 Traffic Real Time Query

    题目内容 洛谷链接 给出一个\(n\)个节点,\(m\)条边的无向图和两个节点\(s\)和\(t\),问这两个节点的路径中有几个点必须经过. 输入格式 第一行是\(n\)和\(m\). 接下来\(m\ ...

  6. CH#24C 逃不掉的路 和 HDU3686 Traffic Real Time Query System

    逃不掉的路 CH Round #24 - 三体杯 Round #1 题目描述 现代社会,路是必不可少的.任意两个城镇都有路相连,而且往往不止一条.但有些路连年被各种XXOO,走着很不爽.按理说条条大路 ...

  7. HDU Traffic Real Time Query System

    题目大意是:对于(n, m)的图,给定边a, b查询从a到b要经过的割点的最少数目. 先tarjan算法求双连通然后缩点,即对于每个割点将周围的每个双连通看成一个点与之相连.然后求解LCA即可,距离d ...

  8. HDU3686 Traffic Real Time Query System 题解

    题目 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, t ...

  9. Traffic Real Time Query System 圆方树+LCA

    题目描述 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, ...

随机推荐

  1. vue.js过度&动画、混入&插件

    1.vue  过度动画 1.过度 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果.Vue 提供了内置的过渡封装组件,该组件用于包裹要实现过渡效果的组件. 语法格式: < ...

  2. element-ui的tabs默认选中页签

    Element-UI提供了tabs组件(选项卡.多页签),其中在tabs的属性中提供了一个value/v-model属性来绑定默认选中的页签. 我们通过简单的示例来看一下具体是怎么使用的. <t ...

  3. jwt入门

    JWT(JSON Web Token)是一个非常轻巧的规范,这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息,通常使用在HTTP通信过程中进行身份认证. 我们知道,HTTP通信是无状态的 ...

  4. C# 学习笔记 多态(一)虚方法

    在面对对象编程中,类的三大特性分别为封装,继承,多态.其中多态的具体实现,依赖于三个方法,也就是虚方法,抽象类和接口. 多态的具体作用是什么呢?或者说多态的存在有什么意义呢?多态的存在有效的降低了程序 ...

  5. pip下载速度慢解决方法

    添加镜像链接 解决方式: 更改pip的数据源.目前国内比较知名的有豆瓣的,清华的.都是pipy官网的镜像. 清华:https://pypi.tuna.tsinghua.edu.cn/simple 阿里 ...

  6. ASP.NET Core系列:读取配置文件

    1. 控制台应用 新建一个控制台应用,添加两个Package: Install-Package Microsoft.Extensions.Configuration Install-Package M ...

  7. python 使用turtule绘制递归图形(螺旋、二叉树、谢尔宾斯基三角形)

    插图工具使用Python内置的turtle模块,为什么叫这个turtle乌龟这个名字呢,可以这样理解,创建一个乌龟,乌龟能前进.后退.左转.右转,乌龟的尾巴朝下,它移动时就会画一条线.并且为了增加乌龟 ...

  8. Vue-组件模板抽离的写法

    VUE的模板分离写法. 1.第一种(不常用) <script type="text/x-template" id="myCpm"> <div& ...

  9. Android源码分析(一)-----如何快速掌握Android编译文件

    一 : Android.mk文件概述 主要向编译系统指定相应的编译规则.会被解析一次或多次.因此尽量减少源码中声明变量,因为这些变量可能会被多次定义从而影响到后面的解析.这个文件的语法会把源代码组织成 ...

  10. Ubuntu下搭建Kubernetes集群(1)--安装docker

    可以使用物理机,也可以使用虚拟机. 首先参考https://docs.docker.com/install/linux/docker-ce/ubuntu/ 官方文档学会安装docker. 1.首先移除 ...