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;
}

posted on 2016-03-04 14:17  wuyuhan  阅读(177)  评论(0编辑  收藏  举报

导航