[BZOJ][Ahoi2008]Meet 紧急集合

题解:枚举三种情况的lca作为集合点 取最优的情况即可

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define link(x) for(edge *j=h[x];j;j=j->next)
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=5e5+10;
const double eps=1e-8;
#define ll long long
using namespace std;
const int inf=1e9;
struct edge{int t;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
void add(int x,int y){o->t=y;o->next=h[x];h[x]=o++;}
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int dis[MAXN];
int dep[MAXN],fa[MAXN],son[MAXN],num[MAXN];
void dfs(int x,int pre,int deep){
    dep[x]=deep+1;fa[x]=pre;num[x]=1;
    link(x){
	if(j->t==pre)continue;
	dis[j->t]=dis[x]+1;
	dfs(j->t,x,deep+1);
	num[x]+=num[j->t];
	if(son[x]==-1||num[son[x]]<num[j->t])son[x]=j->t;
    }
}

int tp[MAXN];
void dfs1(int x,int td){
    tp[x]=td;
    if(son[x]!=-1)dfs1(son[x],td);
    link(x){
	if(j->t==fa[x]||j->t==son[x])continue;
	dfs1(j->t,j->t);
    }
}

int Lca(int x,int y){
    int xx=tp[x];int yy=tp[y];
    while(xx!=yy){
	if(dep[xx]<dep[yy])swap(xx,yy),swap(x,y);
	x=fa[xx];xx=tp[x];
    }
    if(dep[x]>dep[y])swap(x,y);
    return x;
}

int main(){
    int n=read();int m=read();
    inc(i,1,n)son[i]=-1;
    int u,v;
    inc(i,2,n)u=read(),v=read(),add(u,v),add(v,u);
    dfs(1,0,0);dfs1(1,1);
    int x,y,z;
    while(m--){
	x=read();y=read();z=read();int ans,pos,lca,lca1,ans1;
	ans=ans1=inf;
	lca=Lca(x,y);lca1=Lca(lca,z);ans1=min(ans,dis[x]+dis[y]-2*dis[lca]+dis[lca]+dis[z]-2*dis[lca1]);
	if(ans1!=ans)ans=ans1,pos=lca;
	lca=Lca(x,z);lca1=Lca(lca,y);ans1=min(ans,dis[x]+dis[z]-2*dis[lca]+dis[lca]+dis[y]-2*dis[lca1]);
	if(ans1!=ans)ans=ans1,pos=lca;
	lca=Lca(y,z);lca1=Lca(lca,x);ans1=min(ans,dis[y]+dis[z]-2*dis[lca]+dis[lca]+dis[x]-2*dis[lca1]);
	if(ans1!=ans)ans=ans1,pos=lca;
	printf("%d %d\n",pos,ans);
    }
    return 0;
}

  

1787: [Ahoi2008]Meet 紧急集合

Time Limit: 20 Sec  Memory Limit: 162 MB
Submit: 4479  Solved: 2153
[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

Sample Output


5 2
2 5
4 1
6 0
posted @ 2019-01-29 15:16  wang9897  阅读(142)  评论(0编辑  收藏  举报