# BZOJ 1787 紧急集合

## 1787: [Ahoi2008]Meet 紧急集合

Time Limit: 20 Sec  Memory Limit: 162 MB
Submit: 1220  Solved: 500
[Submit][Status]

6 4
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6

5 2
2 5
4 1
6 0

## HINT

——分割线——

/*Author:WNJXYK*/
#include<cstdio>
using namespace std;

#define LL long long

const int Maxn=500000;
int n,m;
struct Node{
int u;
int nxt;
Node(){}
Node(int a,int b){
u=a;
nxt=b;
}
};
int nume=0;
int visited[Maxn+10];
int lca[Maxn+10][20];
int depth[Maxn+10];
int Mlca=20;

int dfs(int x,int deep){
depth[x]=deep;
visited[x]=true;
for(int i=1;i<Mlca;i++){
lca[x][i]=lca[lca[x][i-1]][i-1];
}
if (!visited[point]){
lca[point][0]=x;
dfs(point,deep+1);
}
}
}

inline void swin(int &x,int step){
for (int i=0;step>0;i++){
if (step%2==1) x=lca[x][i];
step/=2;
}
}

inline void swap(int &x,int &y){
x=x+y;
y=x-y;
x=x-y;
}

inline int LCA(int x,int y){
if (depth[x]>depth[y]) swap(x,y);
swin(y,depth[y]-depth[x]);
if (x==y) return x;
for (int i=0;;){
for(i=0;lca[x][i]!=lca[y][i];i++);
if (i==0) return lca[x][i];
x=lca[x][i-1];
y=lca[y][i-1];
}
return -1;
}

inline void addEdge(int x,int y){
}

inline int dist(int x,int y){
int l=LCA(x,y);
return depth[x]+depth[y]-2*depth[l];
}

int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
}
lca[1][0]=1;
dfs(1,1);
for (int i=1;i<=m;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
int lx,ly,lz;
lx=LCA(x,y);
ly=LCA(y,z);
lz=LCA(z,x);
//cout<<lx<<" "<<ly<<" "<<lz<<" "<<endl;
int l=lx^ly^lz;
int ans=dist(l,x)+dist(l,y)+dist(l,z);
printf("%d %d\n",l,ans);
}
return 0;
}


posted @ 2014-10-21 23:19  WNJXYK  阅读(122)  评论(0编辑  收藏  举报