bzoj1832: [AHOI2008]聚会 LCA

来源:互联网 发布:php 打印二维数组 编辑:程序博客网 时间:2024/05/16 18:12
一看就是LCA,输入a,b,c集中的点肯定在LCA(a,b) 或LCA(c,b)或LCA(a,c)上,取最小值就可以了。
#include <iostream>#include <cstring>#include <algorithm>#include <cmath>#include <cstdio>#include <queue>using namespace std;#define maxn 510000#define deg 20int fa[maxn][deg],n,f1,f2,num,m,in[maxn<<1],ceng[maxn<<1];int first[maxn<<1],next[maxn<<1],to[maxn<<1];void build(int a,int b){    to[num]=b;    next[num]=first[a];    first[a]=num;    num++;}void bfs(int root){    queue<int>que;    ceng[root] = 1;    fa[root][0] = root;    que.push(root);    while(!que.empty())    {        int tmp = que.front();        que.pop();        for(int i = 1;i < deg;i++)            fa[tmp][i] = fa[fa[tmp][i-1]][i-1];        for(int i = first[tmp]; i != -1;i =next[i])        {            int v = to[i];            if(ceng[v])continue;            ceng[v] = ceng[tmp] + 1;            fa[v][0] = tmp;            que.push(v);        }    }} int LCA(int u,int v){    if(ceng[u]<ceng[v])        swap(u,v);    int du,dv;    du=ceng[u];    dv=ceng[v];    int tu=u,tv=v;    for(int i=19;i>=0;i--)    {        if(ceng[fa[tu][i]]>=ceng[tv])        {            tu=fa[tu][i];        }    }    if(tu==tv)    {        return tu;    }     for(int i=deg-1;i>=0;i--)    {        if(fa[tu][i]==fa[tv][i])            continue;        tv=fa[tv][i];        tu=fa[tu][i];    }    return fa[tu][0];}int get(int a,int b,int c){    int tmp;    f1=LCA(a,b);    f2=LCA(f1,c);    tmp=abs(ceng[f1]-ceng[a])+abs(ceng[f1]-ceng[b])+abs(ceng[f2]-ceng[f1])+abs(ceng[f2]-ceng[c]);    return tmp;}int main(){         int a,b,c,cas,dis;    scanf("%d%d",&n,&cas);    memset(in,0,sizeof(in));    memset(first,-1,sizeof(first));    memset(ceng,0,sizeof(ceng));    for(int i=1;i<n;i++)    {        scanf("%d%d",&a,&b);        build(a,b);        build(b,a);    }    bfs(1);    int ans,pos;    for(int i=1;i<=cas;i++)    {        ans=0x3f3f3f3f;        scanf("%d%d%d",&a,&b,&c);        dis=get(a,b,c);        if(ans>dis) pos=f1,ans=dis;        dis=get(a,c,b);        if(ans>dis) pos=f1,ans=dis;        dis=get(b,c,a);        if(ans>dis) pos=f1,ans=dis;        printf("%d %d\n",pos,ans);    }    return 0;}

0 0
原创粉丝点击