zoukankan      html  css  js  c++  java
  • 树剖求LCA模板

    •  O(logn)(n<=10^6)
    • https://www.cnblogs.com/cangT-Tlan/p/8846408.html
    • 把一棵树分成几条链,用数据结构去维护每一条链
    •  1 #include<bits/stdc++.h>
       2 #define ll long long
       3 #define rll register ll
       4 #define M 0x3f3f3f
       5 #define For(i,l,r) for(int i=l;i<=r;i++)
       6 using namespace std; 
       7 ll n,m,s,head[M],a[M],x,y,z,tot,k,t;
       8 ll fa[M],d[M],top[M],size[M],id[M],ril[M];
       9 struct node1{
      10     ll to,nxt;
      11 }e[M<<1];
      12 struct node2{
      13     ll l,r,sum,flag;
      14 }tree[M<<1];
      15 
      16 inline ll read(){
      17     ll f=1,sum=0;
      18     char ch=getchar();
      19     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
      20     while(isdigit(ch)){sum=(sum<<1)+(sum<<3)+(ch^48);ch=getchar();}
      21     return f*sum;
      22 }
      23 
      24 inline void add(ll x,ll y){
      25     e[++tot].to=y;
      26     e[tot].nxt=head[x];
      27     head[x]=tot;
      28 }
      29 
      30 inline void dfs1(ll u){//第一遍dfs遍历树,预处理d深度,size此点子节点个数,fa其父节点
      31     d[u]=d[fa[u]]+1;
      32     size[u]=1;
      33     for(rll i=head[u];i;i=e[i].nxt){
      34         if(e[i].to!=fa[u]){
      35             fa[e[i].to]=u;
      36             dfs1(e[i].to);
      37             size[u]+=size[e[i].to];
      38         }
      39     }
      40 }
      41 
      42 inline void dfs2(ll u){//按照子节点个数多少划分轻重边,保证一个点只在一条链中。一般只用重边,轻边用不到。
      43     ll t=0;//top即为此点所在重边的顶点 
      44     if(!top[u]) top[u]=u;
      45     for(rll i=head[u];i;i=e[i].nxt){
      46         if(e[i].to!=fa[u]&&size[e[i].to]>t) t=e[i].to;
      47     }
      48     if(t){
      49         top[t]=top[u];
      50         dfs2(t);
      51     }
      52     for(rll i=head[u];i;i=e[i].nxt){
      53         if(e[i].to!=fa[u]&&e[i].to!=t) dfs2(e[i].to); 
      54     }
      55 }
      56 
      57 inline ll lca(ll x,ll y){//当两个点位于同一条重链上即结束操作。否则深度深的点跳到所在重链的上一个点,结束操作时深度浅的点的位置即为所求lca
      58     while(top[x]!=top[y]){
      59         if(d[top[x]]<d[top[y]]) swap(x,y);
      60         x=fa[top[x]];
      61     }
      62     if(d[x]>d[y]) swap(x,y);
      63     return x;
      64 }
      65 
      66 int main(){
      67     n=read(),m=read(),s=read();
      68     For(i,1,n-1) {x=read(),y=read(),add(x,y),add(y,x);}
      69     dfs1(s),dfs2(s);
      70     For(i,1,m){x=read(),y=read(),printf("%lld
      ",lca(x,y));}
      71     return 0;
      72 }
  • 相关阅读:
    谷歌地球服务器"失联"的替代方案
    Win32Api -- 回到Windows桌面
    WPF -- 应用启动慢问题
    Windows -- 多网卡上网设置
    .Net -- ConfigurationSection的简单使用
    WPF -- 使用RenderTargetBitmap将Canvas保存为图片
    WPF -- 使用当前进程打开自定义文件的一种方式
    WPF源码阅读 -- InkCanvas选中笔迹
    WPF源码阅读 -- InkCanvas选择模式
    WPF -- 使用Blend工具绘制Control样式
  • 原文地址:https://www.cnblogs.com/wi1d3on/p/11330922.html
Copyright © 2011-2022 走看看