欢迎来到SFWR的博客

BZOJ1787: [Ahoi2008]Meet 紧急集合

 

 


LCA倍增+大眼观察


#include<bits/stdc++.h>
using namespace std;
int n,m,a,b,ne,c,head[1001000],fa[501000][26],d[501000];
struct node{int nxt,v;}eg[1001000];
void adde(int u,int v){eg[++ne].v=v;eg[ne].nxt=head[u];head[u]=ne;}
void dfs(int u)
{
    for(int i=head[u];i;i=eg[i].nxt)
    if(eg[i].v!=fa[u][0]){d[eg[i].v]=d[u]+1;fa[eg[i].v][0]=u;dfs(eg[i].v);}
}
int lca(int x,int y)
{
    if(d[x]<d[y])swap(x,y);
    for(int i=24;i>=0;i--)
    if(d[fa[x][i]]>=d[y])x=fa[x][i];
    if(x==y)return x;
    for(int i=24;i>=0;i--)if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];}
    return fa[x][0];
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<n;i++){scanf("%d%d",&a,&b);adde(a,b);adde(b,a);}
    d[0]=-1;dfs(1);
    for(int i=1;i<=24;i++)for(int j=1;j<=n;j++)
    fa[j][i]=fa[fa[j][i-1]][i-1];
    while(m--)
    {
        scanf("%d%d%d",&a,&b,&c);
        int t1=lca(a,b),t2=lca(b,c),t3=lca(a,c),t;
        if(t1==t2)t=t3;
        else if(t1==t3)t=t2;
        else if(t2==t3)t=t1;
        int ans=d[a]+d[b]+d[c]-d[t1]-d[t2]-d[t3];
        printf("%d %d\n",t,ans);
    }
}

 

 

posted @ 2019-11-14 11:20  SFWR  Views(78)  Comments(0Edit  收藏  举报