首页 > 代码库 > bzoj 1787: [Ahoi2008]Meet 紧急集合

bzoj 1787: [Ahoi2008]Meet 紧急集合

1787: [Ahoi2008]Meet 紧急集合

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

HINT

技术分享

Source

Day1

 

lca

屠龙宝刀点击就送

#include <ctype.h>#include <cstring>#include <cstdio>#define N 500005void read (int &x){    x=0;    char ch=getchar();    while (!isdigit(ch)) ch=getchar();    while (isdigit(ch)) x=x*10+ch-0,ch=getchar();}struct node{    int next,to;}edge[N<<1];int dep[N],head[N<<1],cnt,n,m,dad[N][25];void add(int u,int v){    cnt++;    edge[cnt].next=head[u];    edge[cnt].to=v;    head[u]=cnt;}void dfs(int x){    dep[x]=dep[dad[x][0]]+1;    for(int i=0;dad[x][i];i++)    dad[x][i+1]=dad[dad[x][i]][i];    for(int i=head[x];i;i=edge[i].next)    {        if(dad[x][0]!=edge[i].to)        {            dad[edge[i].to][0]=x;            dfs(edge[i].to);        }    }}void swap(int &x,int &y){    int tmp=x;    x=y;    y=tmp;} int lca(int x,int y){    if(dep[x]>dep[y]) swap(x,y);    for(int i=20;i>=0;i--)    if(dep[dad[y][i]]>=dep[x]) y=dad[y][i];    if(x==y) return x;    for(int i=20;i>=0;i--)     if(dad[x][i]!=dad[y][i]) x=dad[x][i],y=dad[y][i];    return dad[x][0];}int main(){    read(n);read(m);    for(int x,y,i=1;i<n;i++)    {        scanf("%d%d",&x,&y);        add(x,y);        add(y,x);    }    dfs(1);    for(int x,y,z,i=1;i<=m;i++)    {        read(x);read(y);read(z);        int root=lca(x,y)^(lca(x,z))^(lca(y,z));        int ans=dep[x]+dep[root]-2*dep[lca(x,root)];        ans+=dep[y]+dep[root]-2*dep[lca(y,root)];        ans+=dep[z]+dep[root]-2*dep[lca(z,root)];        printf("%d %d\n",root,ans);     }    return 0;}

 

 

bzoj 1787: [Ahoi2008]Meet 紧急集合