【bzoj1787】&【bzoj1832】[Ahoi2008]Meet 紧急集合 & 聚会

bzoj1787就是bzoj1832

bzoj1832 空间和时间少了一些。。。

 

求三个结点到一个结点距离之和最小的结点以及距离和

求出两两lca,其中有两个相同,答案则为另一个

 

感觉就是一大暴力。。。

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #include<queue>
  8 using namespace std;
  9  
 10 #define N 500010
 11  
 12 struct edge
 13 {
 14     int to,next;
 15 }e[N<<2];
 16 int head[N<<2];
 17 int cnt;
 18  
 19 int fa[N][20],dep[N];
 20  
 21 bool vis[N];
 22  
 23 int n,q;
 24 int u,v,w;
 25 int p1,p2,p3;
 26 int t;
 27 int ans;
 28  
 29 void link(int x,int y)
 30 {
 31     e[++cnt]=(edge){x,head[y]};
 32     head[y]=cnt;
 33 }
 34  
 35 void dfs(int x)
 36 {
 37     vis[x]=1;
 38     for (int i=1;i<=18;i++)
 39     {
 40         if (dep[x]<(1<<i))
 41             break;
 42         fa[x][i]=fa[fa[x][i-1]][i-1];
 43     }
 44     for (int i=head[x];i;i=e[i].next)
 45     {
 46         int t=e[i].to;
 47         if (vis[t])
 48             continue;
 49         dep[t]=dep[x]+1;
 50         fa[t][0]=x;
 51         dfs(t);
 52     }
 53 }
 54  
 55 int lca(int x,int y)
 56 {
 57     if (dep[x]<dep[y])
 58         swap(x,y);
 59     int t=dep[x]-dep[y];
 60     for (int i=18;i>=0;i--)
 61         if (t & (1<<i))
 62             x=fa[x][i];
 63     if (x==y)
 64         return x;
 65     for (int i=18;i>=0;i--)
 66         if (fa[x][i]!=fa[y][i])
 67             x=fa[x][i],y=fa[y][i];
 68     return fa[x][0];
 69 }
 70  
 71 int dis(int x,int y)
 72 {
 73     int k=lca(x,y);
 74     return dep[x]+dep[y]-(dep[k]<<1);
 75 }
 76  
 77 int main()
 78 {
 79     scanf("%d%d",&n,&q);
 80     for (int i=1;i<n;i++)
 81     {
 82         scanf("%d%d",&u,&v);
 83         link(u,v);
 84         link(v,u);
 85     }
 86     dfs(1);
 87     while (q--)
 88     {
 89         scanf("%d%d%d",&u,&v,&w);
 90         p1=lca(u,v);
 91         p2=lca(u,w);
 92         p3=lca(v,w);
 93         if (p1==p2)
 94             t=p3;
 95         else if (p1==p3)
 96             t=p2;
 97         else
 98             t=p1;
 99         ans=dis(u,t)+dis(v,t)+dis(w,t);
100         printf("%d %d\n",t,ans);
101     }
102     return 0;
103 }

 

posted @ 2016-05-14 22:27  Yangjiyuan  阅读(190)  评论(0编辑  收藏  举报