码迷,mamicode.com
首页 > 其他好文 > 详细

Tarjan_LCA

时间:2016-08-18 14:23:57      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:

貌似求LCA使用倍增已经可以应付掉大多数需要LCA的题了..

但是有些时候O(MlogN)的复杂度就不可接受了

 

Tarjan_LCA对于每个询问采用离线处理

总复杂度为O(M+N)

这个复杂度几乎不可能被卡掉

 

简单说的话用Tarjan求LCA就是根据后序dfs的框架然后用并查集加持。

具体实现过程参加代码。

 

 

用HUD2586作为模板

 

 

 1 //HUD 2586 Tarjan_LCA
 2 //by Cydiater
 3 //2016.8.15
 4 #include <iostream>
 5 #include <cstring>
 6 #include <string>
 7 #include <cstdio>
 8 #include <cstdlib>
 9 #include <cmath>
10 #include <ctime>
11 #include <queue>
12 #include <map>
13 #include <iomanip>
14 #include <algorithm>
15 using namespace std;
16 #define ll long long
17 #define up(i,j,n)       for(int i=j;i<=n;i++)
18 #define down(i,j,n)     for(int i=j;i>=n;i--)
19 const int MAXN=1e6+5;
20 const int oo=0x3f3f3f3f;
21 inline int read(){
22       char ch=getchar();int x=0,f=1;
23       while(ch>9||ch<0){if(ch==-)f=-1;ch=getchar();}
24       while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
25       return x*f;
26 }
27 int N,M,LINK[MAXN],len=0,dis[MAXN],fa[MAXN],tol=0,Link[MAXN],g[MAXN],T,ans[MAXN];
28 bool vis[MAXN];
29 struct edge{int y,next,v;}e[MAXN];
30 struct query{int y,next,lca;}q[MAXN];
31 namespace solution{
32       inline void insert(int x,int y,int v){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].v=v;}
33       inline void Insert(int x,int y){q[++tol].next=Link[x];Link[x]=tol;q[tol].y=y;}
34       int get(int k){
35             if(g[k]==k) return k;
36             g[k]=get(g[k]);
37             return g[k];
38       }
39       void dfs(int node,int dist,int father){
40             fa[node]=father;dis[node]=dist;
41             for(int i=LINK[node];i;i=e[i].next)
42                   if(e[i].y!=father)
43                         dfs(e[i].y,dist+e[i].v,node);
44       }
45       void init(){
46             N=read();M=read();
47             up(i,1,N-1){
48                   int x=read(),y=read(),v=read();
49                   insert(x,y,v);
50                   insert(y,x,v);
51             }
52             memset(fa,0,sizeof(fa));
53             memset(dis,0,sizeof(dis));
54             memset(vis,0,sizeof(vis));
55             dfs(1,0,0);
56             up(i,1,M){
57                   int x=read(),y=read();
58                   Insert(x,y);
59             }
60       }
61       void lca(int node){
62             vis[node]=1;g[node]=node;
63             for(int i=LINK[node];i;i=e[i].next)
64                   if(!vis[e[i].y]){
65                         lca(e[i].y);
66                         g[e[i].y]=node;
67                   }
68             for(int i=Link[node];i;i=q[i].next)
69                   if(vis[q[i].y]){
70                         q[i].lca=get(q[i].y);
71                         ans[i]=dis[node]+dis[q[i].y]-2*dis[q[i].lca];
72                   }
73       }
74       void output(){
75             up(i,1,M)printf("%d\n",ans[i]);
76       }
77 }
78 int main(){
79       //freopen("input.in","r",stdin);
80       using namespace solution;
81       T=read();
82       while(T--){
83             tol=0;len=0;
84             memset(Link,0,sizeof(Link));
85             memset(LINK,0,sizeof(LINK));
86             init();
87             lca(1);
88             output();
89       }
90       return 0;
91 }

Tarjan_LCA

标签:

原文地址:http://www.cnblogs.com/Cydiater/p/5783569.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!