BZOJ 1787: [Ahoi2008]Meet 紧急集合
BZOJ 1787: [Ahoi2008]Meet 紧急集合
标签(空格分隔): OI-BZOJ OI-LCA
Time Limit: 20 Sec
Memory Limit: 162 MB
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
Sample Output
5 2
2 5
4 1
6 0
HINT
Solution####
枚举两两的lca作为答案求最小
Code####
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<bitset>
#include<vector>
using namespace std;
int read()
{
int s=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-'0';ch=getchar();}
return s*f;
}
//smile please
int n,m;
int be[500005],bn[1000005],bv[1000005],bw=1;
int dep[500005],f[500005][19];
void put(int u,int v)
{bw++;bn[bw]=be[u];be[u]=bw;bv[bw]=v;}
void dfs(int x)
{
for(int i=be[x];i;i=bn[i])
if(bv[i]!=f[x][0])
dep[bv[i]]=dep[x]+1,
f[bv[i]][0]=x,
dfs(bv[i]);
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
for(int i=18;i>=0;i--)
if(dep[f[x][i]]>=dep[y])
x=f[x][i];
for(int i=18;i>=0;i--)
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
return x==y?y:f[x][0];
}
int an1,an2;
int main()
{
n=read(),m=read();
for(int i=1;i<n;i++)
{int u=read(),v=read();
put(u,v),put(v,u);
}
dep[1]=1;dfs(1);
for(int i=1;i<=18;i++)
for(int j=1;j<=n;j++)
f[j][i]=f[f[j][i-1]][i-1];
for(;m--;)
{int a=read(),b=read(),c=read();
int x,y;
x=lca(a,b);y=lca(x,c);
an1=x,an2=dep[a]-dep[x]+dep[b]+dep[c]-dep[y]*2;
x=lca(a,c);y=lca(x,b);
if(an2>dep[a]-dep[x]+dep[c]+dep[b]-dep[y]*2)
an1=x,an2=dep[a]-dep[x]+dep[c]+dep[b]-dep[y]*2;
x=lca(c,b);y=lca(x,a);
if(an2>dep[c]-dep[x]+dep[b]+dep[a]-dep[y]*2)
an1=x,an2=dep[c]-dep[x]+dep[b]+dep[a]-dep[y]*2;
printf("%d %d\n",an1,an2);
}
return 0;
}