dalao的tajan模板

来源:互联网 发布:双色球七加一中奖算法 编辑:程序博客网 时间:2024/05/15 23:54

lca:最近公共祖先

求LCA一般有用倍增的和tarjan的,
倍增的是O(nlogn)的但是可以在线;
tarjan是O(n+Q)的但是必须离线。
应当对于不同的题目适当选择。

tarjan算法的主要思想……是从要求的一对点的访问过程求来的。
比如以一个点u为根的多个小子树内,不同小子树内的点对的lca都是u。
那么可以dfs下去,回上去的时候用并查集合并整棵子树。

看懂网上的或者书上的资料之后代码其实是很简洁的……
模板题目网址

#include<bits/stdc++.h>  using namespace std;  int read(){      int x=0,f=1;char ch=getchar();      while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}      while (ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}      return x*f;  }  const int           N=500005;  int n,m,S;  int Qcnt,Ecnt;  int fa[N],ans[N];  bool vis[N];  struct Edge{      int next,to;  }E[N<<1];int head[N];  struct Query{      int next,to,id;  }Q[N<<1];int qh[N];  int getfa(int u){      if (fa[u]!=u) fa[u]=getfa(fa[u]);      return fa[u];  }  void add(int u,int v){      E[++Ecnt].next=head[u];      E[Ecnt].to=v;      head[u]=Ecnt;  }  void add1(int u,int v,int t){      Q[++Qcnt].next=qh[u];      Q[Qcnt].to=v;      Q[Qcnt].id=t;      qh[u]=Qcnt;  }  void tarjan(int u){      vis[u]=1,fa[u]=u;      for (int i=head[u];i;i=E[i].next){          int j=E[i].to;          if (!vis[j]) tarjan(j),fa[j]=u;      }      for (int i=qh[u];i;i=Q[i].next){          int j=Q[i].to;          if (vis[j]) ans[Q[i].id]=getfa(j);      }  }  int main(){      n=read(),m=read(),S=read();      int x,y;      for (int i=1;i<n;i++){          x=read(),y=read();          add(x,y),add(y,x);      }      for (int i=1;i<=m;i++){          x=read(),y=read();          add1(x,y,i),add1(y,x,i);      }      tarjan(S);      for (int i=1;i<=m;i++)          printf("%d\n",ans[i]);      return 0;  }  

%dalao% orz
出处:%dalao%

原创粉丝点击