\(\mathcal{Description}\)

  Link.

  给定一个 \(n\) 个点 \(m\) 条边的连通无向图,并给出 \(q\) 个点对 \((u,v)\),询问 \(u\) 到 \(v\) 的路径所必经的结点个数。

  \(n,q\le5\times10^5\),\(q\le\min\{\frac{n(n-1)}2,10^6\}\)。

\(\mathcal{Solution}\)

  大概是双倍经验吧。

  建出圆方树,预处理圆方树上每个点到根经过的圆点个数,然后求 LCA 计算答案即可。

  复杂度 \(\mathcal O(n\log n)-\mathcal O(\log n)\)。

\(\mathcal{Code}\)

  1. #include <cstdio>
  2. const int MAXN = 5e5, MAXM = 1e6;
  3. int n, m, q, snode;
  4. int dfc, top, dfn[MAXN + 5], low[MAXN + 5], stk[MAXN + 5];
  5. int dep[MAXN * 2 + 5], cnt[MAXN * 2], fa[MAXN * 2 + 5][20];
  6. struct Graph {
  7. int ecnt, head[MAXN * 2 + 5], to[MAXM * 2 + 5], nxt[MAXM * 2 + 5];
  8. inline void link ( const int s, const int t ) {
  9. to[++ ecnt] = t, nxt[ecnt] = head[s];
  10. head[s] = ecnt;
  11. }
  12. inline void add ( const int u, const int v ) {
  13. link ( u, v ), link ( v, u );
  14. }
  15. } src, tre;
  16. inline bool chkmin ( int& a, const int b ) { return b < a ? a = b, true : false; }
  17. inline void Tarjan ( const int u, const int f ) {
  18. dfn[u] = low[u] = ++ dfc, stk[++ top] = u;
  19. for ( int i = src.head[u], v; i; i = src.nxt[i] ) {
  20. if ( ( v = src.to[i] ) == f ) continue;
  21. if ( ! dfn[v] ) {
  22. Tarjan ( v, u ), chkmin ( low[u], low[v] );
  23. if ( low[v] >= dfn[u] ) {
  24. tre.add ( u, ++ snode );
  25. do tre.add ( snode, stk[top] ); while ( stk[top --] ^ v );
  26. }
  27. } else chkmin ( low[u], dfn[v] );
  28. }
  29. }
  30. inline void init ( const int u, const int f ) {
  31. dep[u] = dep[fa[u][0] = f] + 1, cnt[u] = cnt[f] + ( u <= n );
  32. for ( int i = 1; i <= 19; ++ i ) fa[u][i] = fa[fa[u][i - 1]][i - 1];
  33. for ( int i = tre.head[u], v; i; i = tre.nxt[i] ) {
  34. if ( ( v = tre.to[i] ) ^ f ) {
  35. init ( v, u );
  36. }
  37. }
  38. }
  39. inline int calcLCA ( int u, int v ) {
  40. if ( dep[u] < dep[v] ) u ^= v ^= u ^= v;
  41. for ( int i = 19; ~ i; -- i ) if ( dep[fa[u][i]] >= dep[v] ) u = fa[u][i];
  42. if ( u == v ) return u;
  43. for ( int i = 19; ~ i; -- i ) if ( fa[u][i] ^ fa[v][i] ) u = fa[u][i], v = fa[v][i];
  44. return fa[u][0];
  45. }
  46. int main () {
  47. scanf ( "%d %d", &n, &m ), snode = n;
  48. for ( int i = 1, u, v; i <= m; ++ i ) {
  49. scanf ( "%d %d", &u, &v );
  50. src.add ( u, v );
  51. }
  52. Tarjan ( 1, 0 ), init ( 1, 0 );
  53. scanf ( "%d", &q );
  54. for ( int i = 1, u, v; i <= q; ++ i ) {
  55. scanf ( "%d %d", &u, &v );
  56. int w = calcLCA ( u, v );
  57. printf ( "%d\n", cnt[u] + cnt[v] - cnt[w] - cnt[fa[w][0]] );
  58. }
  59. return 0;
  60. }

Solution -「洛谷 P4320」道路相遇的更多相关文章

  1. Solution -「洛谷 P4372」Out of Sorts P

    \(\mathcal{Description}\)   OurOJ & 洛谷 P4372(几乎一致)   设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...

  2. Note/Solution -「洛谷 P5158」「模板」多项式快速插值

    \(\mathcal{Description}\)   Link.   给定 \(n\) 个点 \((x_i,y_i)\),求一个不超过 \(n-1\) 次的多项式 \(f(x)\),使得 \(f(x ...

  3. Solution -「洛谷 P4198」楼房重建

    \(\mathcal{Description}\)   Link.   给定点集 \(\{P_n\}\),\(P_i=(i,h_i)\),\(m\) 次修改,每次修改某个 \(h_i\),在每次修改后 ...

  4. Solution -「洛谷 P6577」「模板」二分图最大权完美匹配

    \(\mathcal{Description}\)   Link.   给定二分图 \(G=(V=X\cup Y,E)\),\(|X|=|Y|=n\),边 \((u,v)\in E\) 有权 \(w( ...

  5. Solution -「洛谷 P6021」洪水

    \(\mathcal{Description}\)   Link.   给定一棵 \(n\) 个点的带点权树,删除 \(u\) 点的代价是该点点权 \(a_u\).\(m\) 次操作: 修改单点点权. ...

  6. Solution -「洛谷 P4719」「模板」"动态 DP" & 动态树分治

    \(\mathcal{Description}\)   Link.   给定一棵 \(n\) 个结点的带权树,\(m\) 次单点点权修改,求出每次修改后的带权最大独立集.   \(n,m\le10^5 ...

  7. Solution -「洛谷 P5236」「模板」静态仙人掌

    \(\mathcal{Description}\)   Link.   给定一个 \(n\) 个点 \(m\) 条边的仙人掌,\(q\) 组询问两点最短路.   \(n,q\le10^4\),\(m\ ...

  8. Solution -「洛谷 P5827」边双连通图计数

    \(\mathcal{Description}\)   link.   求包含 \(n\) 个点的边双连通图的个数.   \(n\le10^5\). \(\mathcal{Solution}\)    ...

  9. Solution -「洛谷 P5827」点双连通图计数

    \(\mathcal{Description}\)   link.   求有 \(n\) 个结点的点双连通图的个数,对 \(998244353\) 取模.   \(n\le10^5\). \(\mat ...

随机推荐

  1. Golang实现集合(set)

    package set package set import ( "bytes" "fmt" "sync" ) type Set struc ...

  2. Hadoop的Shuffle阶段

    原文: https://www.toutiao.com/i6764683672772674062/ 在进入Map之前,首先会将数据从HDFS中读取,进行处理,按照字节偏移量这种之前说的形式处理为K,V ...

  3. vue 前进刷新后退不刷新

    这边是router-view部门的写法: <keep-alive> <router-view v-if="$route.meta.keepAlive"/> ...

  4. vue部署服务器以及解决部署到apache路由出现404

    最近在开发cms的时候使用Vue.js框架,利用vue-route.vue-cli结合webpack编写了一个单页路由项目,自己在服务器端配置apache.部署完成后,访问没问题,从页面中点击跳转就会 ...

  5. 灵雀云Kube-OVN:基于OVN的开源Kubernetes网络实践

    近日,灵雀云发布了基于OVN的Kubernetes网络组件Kube-OVN,并正式将其在Github上开源.Kube-OVN提供了大量目前Kubernetes不具备的网络功能,并在原有基础上进行增强. ...

  6. RHCSA 第三天

    1.将echo "This is my first time to use pipe"内容输出到屏幕上,且保存到pipe_data.txt中 2. 重定向: a.新建一个文件red ...

  7. 安装MySQL到Ubuntu 20.04

    本文的内容主要来自对How To Install MySQL on Ubuntu 20.04的翻译.在根据该文的指导下,我在自己的Ubuntu 20.04.3 LTS版本中安装了MySQL 8. St ...

  8. 【刷题-LeetCode】202. Happy Number

    Happy Number Write an algorithm to determine if a number n is "happy". A happy number is a ...

  9. 单例模式的各种实现方式(Java)

    单例模式的基础实现方式 手写普通的单例模式要点有三个: 将构造函数私有化 利用静态变量来保存全局唯一的单例对象 使用静态方法 getInstance() 获取单例对象 懒汉模式 懒汉模式指的是单例对象 ...

  10. 学习JAVAWEB第十六天

    今天做了一个简单的登陆界面,HTML+CSS太不熟悉了,明天还得接着做