[模板]LCA

洛谷P3379

注意:不能与LCA搞混(打久了就会发现两个还是有很大区别的)

   位运算一定要加括号!

   for循环从0到logn还是从logn到0看当前的状态更适合哪种

   第53行预处理一定要注意!(因为没有下标为-1的数组)

   第34行也要注意如何判断当前是否跳点(不需要麻烦的位运算,因为如果能跳,dep[y]自然就会变,如果不跳,dep[y]又不变,每次与(dep[y]-dep[x])进行比较,不影响dep[x]与dep[y]的值;

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define man 500010
 4 inline int read()
 5 {    int x=0;bool f=0;
 6     char ch=getchar();
 7     while(ch<'0'||ch>'9'){f=(ch==45);ch=getchar();}
 8     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
 9     return f?(~x+1):x;
10     }
11 int dep[man],f[man][30];
12 int n,m,logn,root;
13 int head[man<<2],num=0;
14 struct edeg
15 {    int next,to;}e[man<<2];
16 inline void add(int from,int to)
17 {    e[++num].next=head[from];
18     e[num].to=to;
19     head[from]=num;
20     }
21 void dfs(int u,int fa,int depth)
22 {    f[u][0]=fa;
23     dep[u]=depth;
24     for(int i=head[u];i;i=e[i].next)
25     {    int to=e[i].to;
26         if(to==fa) continue;
27         dfs(to,u,depth+1);
28         }
29     return ;
30     }
31 inline int LCA(int x,int y)
32 {    if(dep[x]>dep[y]) swap(x,y);
33     for(int i=0;i<logn;i++)
34         if(((dep[y]-dep[x])>>i)&1) y=f[y][i];
35     if(x==y) return x;
36     for(int i=logn;i>=0;i--)
37     {    if(f[x][i]!=f[y][i])
38         {    x=f[x][i];y=f[y][i];
39             }
40         }
41     return f[x][0];
42     }
43 int main()
44 {    n=read(),m=read(),root=read();
45     logn=(int)(log(n)/log(2.0))+1;
46     for(int i=1;i<n;i++)
47     {    int u=read(),v=read();
48         add(u,v);add(v,u);
49         }
50     dfs(root,-1,0);
51     for(int j=0;j<logn;j++)
52         for(int i=1;i<=n;i++)
53             if(f[i][j]<0) f[i][j+1]=-1;
54             else f[i][j+1]=f[f[i][j]][j];
55     for(int i=1;i<=m;i++)
56     {    int x=read(),y=read();
57         printf("%d\n",LCA(x,y));
58         }
59     return 0;
60     }

 LCA使用BFS应该会快一点吧。。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 #define man 500005
 8 int n,m,root;
 9 int head[man<<2],num=0;
10 inline int read()
11 {    int x=0;bool f=0;
12     char ch=getchar();
13     while(ch<'0'||ch>'9'){f=(ch==45);ch=getchar();}
14     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
15     return f?(~x+1):x;
16     }
17 struct edge
18 {    int next,to;}e[man<<2];
19 inline void add(int from,int to)
20 {    e[++num].next=head[from];
21     e[num].to=to;
22     head[from]=num;
23     }
24 int f[man][25],dep[man],logn;
25 bool vis[man];
26 void bfs(int s,int dept)
27 {    memset(vis,0,sizeof(vis));
28     f[s][0]=-1;dep[s]=dept;
29     queue<int>q;
30     q.push(s);
31     do
32     {    int u=q.front();q.pop();vis[u]=1;
33         for(int i=head[u];i;i=e[i].next)
34         {    int to=e[i].to;
35             if(!vis[to])
36             {    f[to][0]=u;
37                 dep[to]=dep[u]+1;
38                 q.push(to);}
39                 }
40         }while(q.size());
41     }
42 inline int LCA(int x,int y)
43 {    if(dep[x]>dep[y]) swap(x,y);
44     for(int i=0;i<logn;i++)
45     {    if(((dep[y]-dep[x])>>i)&1)
46              y=f[y][i];
47         }
48     if(x==y) return x;
49     for(int i=logn;i>=0;i--)
50     {    if(f[x][i]!=f[y][i])
51         {    x=f[x][i];
52             y=f[y][i];
53             }
54         }
55     return f[x][0];
56     }
57 int main()
58 {    n=read(),m=read(),root=read();
59     for(int i=1;i<n;i++)
60     {    int x,y;
61         x=read(),y=read();
62         add(x,y);add(y,x);
63         }
64     bfs(root,0);
65     logn=(int)(log(n)/log(2.0))+1;
66     for(int j=0;j<logn;j++)
67         for(int i=1;i<=n;i++)
68             if(f[i][j]<0) f[i][j+1]=-1;
69             else f[i][j+1]=f[f[i][j]][j];
70     for(int i=1;i<=m;i++)
71     {    int x,y;
72         x=read(),y=read();
73         printf("%d\n",LCA(x,y));
74         }
75     return 0;
76     }

 

 

 

posted @ 2017-11-02 12:51  Slager_Z  阅读(228)  评论(0编辑  收藏  举报
博客园 首页 私信博主 显示目录 隐藏目录 管理 动画