1787: [Ahoi2008]Meet 紧急集合
Submit: 4669 Solved: 2246
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
6 4
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6
Sample Output
5 2
2 5
4 1
6 0
HINT
LCA果然还是玄学,倍增父节点这点理解好久
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 5 const int MAXN=1000005; 6 struct Edge 7 { 8 int to,next; 9 }E[MAXN]; 10 int node,head[MAXN]; 11 int deep[MAXN],fa[MAXN][20]; 12 bool vis[MAXN]; 13 int n,m; 14 15 void insert(int u,int v) 16 { 17 E[++node]=(Edge){v,head[u]};head[u]=node; 18 E[++node]=(Edge){u,head[v]};head[v]=node; 19 } 20 21 void dfs(int x) 22 { 23 vis[x]=1; 24 for(int i=1;i<=18;i++) 25 { 26 if(deep[x]<(1<<i)) break; 27 fa[x][i]=fa[fa[x][i-1]][i-1]; 28 } 29 for(int i=head[x];i;i=E[i].next) 30 { 31 if(vis[E[i].to]) continue; 32 deep[E[i].to]=deep[x]+1; 33 fa[E[i].to][0]=x; 34 dfs(E[i].to); 35 } 36 } 37 38 int lca(int x,int y) 39 { 40 if(deep[x]<deep[y]) swap(x,y); 41 int d=deep[x]-deep[y]; 42 for(int i=0;i<=18;i++) 43 if((1<<i)&d) x=fa[x][i]; 44 for(int i=18;i>=0;i--) 45 if(fa[x][i]!=fa[y][i]) 46 { 47 x=fa[x][i]; 48 y=fa[y][i]; 49 } 50 if(x==y) return x; 51 else return fa[x][0]; 52 } 53 54 int dis(int x,int y) 55 { 56 int t=lca(x,y); 57 return deep[x]+deep[y]-2*deep[t]; 58 } 59 60 int main() 61 { 62 scanf("%d%d",&n,&m); 63 for(int i=1;i<n;i++) 64 { 65 int u,v; 66 scanf("%d%d",&u,&v); 67 insert(u,v); 68 } 69 dfs(1); 70 for(int i=1;i<=m;i++) 71 { 72 int x,y,z; 73 scanf("%d%d%d",&x,&y,&z); 74 int a=lca(x,y),b=lca(x,z),c=lca(y,z),t; 75 if(a==b) t=c; 76 else if(b==c) t=a; 77 else if(a==c) t=b; 78 int ans=dis(x,t)+dis(y,t)+dis(z,t); 79 printf("%d %d\n",t,ans); 80 } 81 return 0; 82 }