关于树上的简单操作(暂时)

戏子无情 提交于 2019-12-04 06:10:27

 

  • 倍增求LCA
 1 #include<cstdio>
 2 #include<iostream>
 3 #define re register
 4 #define in inline
 5 #define N 500010
 6 #define M 500010
 7 using namespace std;
 8 in int read(){
 9     int x=0,f=1; char c=getchar();
10     while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
12     return x*f;
13 }
14 struct node{
15     int next,to;
16 }edge[M<<1];
17 int n,q,s,cnt;
18 int head[M<<1],f[25][N],dep[N]; 
19 
20 in void add(int x,int y){
21     edge[++cnt].next=head[x];
22     edge[cnt].to=y;
23     head[x]=cnt; 
24 }
25 
26 void dfs(int u,int deep){
27     dep[u]=deep;
28     for(re int i=head[u];i;i=edge[i].next){
29         int v=edge[i].to;
30         if(!dep[v]) dfs(v,deep+1);
31         f[0][v]=u;    //特别注意:需在dfs后更新,不然会被更新回去 
32     }                //无向图中要保持向根性,所以if(!dep[v])也必不可少 
33 }
34 
35 in int lca(int x,int y){
36     if(dep[x]<dep[y]) swap(x,y);
37     for(int i=20;i>=0;i--){    //跳至同一深度 
38         if(dep[f[i][x]]>=dep[y])
39         x=f[i][x];
40         if(x==y) return x;    //跳至同一点(x),x即是lca 
41     }
42     
43     for(int i=20;i>=0;i--){
44         if(f[i][x]!=f[i][y])    //不是同一点,往上跳 
45             x=f[i][x],y=f[i][y];
46     }
47     return f[0][x];    //同深度不同点的父节点,即lca 
48 }
49 
50 int main()
51 {
52     n=read(),q=read(),s=read();
53     for(re int i=1;i<n;i++){
54         int u=read(),v=read();
55         add(u,v),add(v,u);
56     }
57     f[0][s]=s;
58     dfs(s,1);
59     for(re int i=1;(1<<i)<=n;i++) //'x<<y' 表示 "x左移2^y" 
60         for(re int j=1;j<=n;j++)
61             f[i][j]=f[i-1][f[i-1][j]];
62     for(re int i=1;i<=q;i++){
63         int x=read(),y=read();
64         printf("%d\n",lca(x,y));
65     }
66     return 0;
67 }

 

 

  • 树上差分
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #define re register
 5 #define in inline
 6 #define N 50010
 7 using namespace std;
 8 int read(){
 9     int x=0,f=1; char c=getchar();
10     while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
12     return x*f;
13     
14 }
15 struct node{
16     int next,to;
17 }edge[N<<1];
18 int n,m,ans,sum,cnt;
19 int head[N<<1],p[N],dep[N],f[N][25];
20 
21 in void add(int x,int y){
22     edge[++cnt].next=head[x];
23     edge[cnt].to=y;
24     head[x]=cnt;
25 }
26 in void solve(int u,int fa){
27     dep[u]=dep[fa]+1,f[u][0]=fa;
28     for(int i=0;f[u][i];i++) f[u][i+1]=f[f[u][i]][i];
29     for(int i=head[u];i;i=edge[i].next){
30         int v=edge[i].to;
31         if(v!=fa) solve(v,u);
32     }
33 }
34 in int LCA(int u,int v){
35     if(dep[u]>dep[v]) swap(u,v);
36     for(re int i=20;i>=0;i--) if(dep[u]<=dep[v]-(1<<i)) v=f[v][i];
37     if(u==v) return u;
38     for(re int i=20;i>=0;i--) if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
39     return f[u][0];
40 }
41 in void get(int u,int fa){
42     for(int i=head[u];i;i=edge[i].next){
43         int v=edge[i].to;
44         if(v!=fa){
45             get(v,u);
46             p[u]+=p[v];
47         }
48     }
49     ans=max(ans,p[u]);
50 }
51 int main()
52 {
53     n=read(),m=read();
54     for(re int i=1;i<n;i++){
55         int u=read(),v=read();
56         add(u,v),add(v,u);
57     }
58     solve(1,0);
59     for(re int i=1;i<=m;i++){
60         int u=read(),v=read();
61         int lca=LCA(u,v);
62         p[u]++,p[v]++,p[lca]--,p[f[lca][0]]--;
63     }
64     get(1,0);
65     printf("%d\n",ans);
66     return 0;
67 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!