AmazingCounters.com

BZOJ 1787: [Ahoi2008]Meet 紧急集合

Description

 

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

思路:唔,直接暴力求出三个lca判断一下哪个lca是题目所要求的点就好了

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 #define maxn 1000009
 6 #define D 20
 7 using namespace std;
 8 int head[maxn],nex[maxn],point[maxn];
 9 int fa[maxn][D+10],x,y,z,now,deep[maxn];
10 void add(int x,int y)
11 {
12     nex[++now] = head[x];
13     head[x] = now;
14     point[now] = y;
15 }
16 void bfs(int s)
17 {
18     queue<int>q;
19     q.push(s);
20     while(!q.empty())
21     {
22         int u = q.front();
23         //printf("%d\n",u);
24         q.pop();
25         for(int i = head[u]; i; i=nex[i])
26         {
27             int k = point[i];
28             if(k == fa[u][0])continue;
29             q.push(k);
30             fa[k][0] = u;
31             for(int j = 1; j < D; j++)fa[k][j] = fa[fa[k][j-1]][j-1];
32             deep[k] = deep[u] + 1;
33         }
34     }
35 }
36 int lca(int x,int y)
37 {
38     if(deep[x]>deep[y])swap(x,y);
39     int tx = x, ty = y,delta = deep[y] - deep[x];
40     for(int i = 0;delta;delta>>=1,i++)if(delta&1)
41     {
42         ty = fa[ty][i];
43     }
44     if(tx == ty)return tx;
45     for(int i = D; i>=0;i--)
46     {
47         if(fa[tx][i] == fa[ty][i])continue;
48         tx = fa[tx][i];
49         ty = fa[ty][i];
50     }
51     return fa[tx][0];
52 }
53  
54 int main()
55 {
56     int n,m;
57     scanf("%d%d",&n,&m);
58     for(int i=1;i<n;i++)
59     {
60         scanf("%d%d",&x,&y);
61         add(x,y);
62         add(y,x);
63     }
64     //puts("0");
65     bfs(1);
66     //puts("1");
67     for(int i = 1; i <= m; i++)
68     {
69         scanf("%d%d%d",&x,&y,&z);
70         int a = lca(x,y),b=lca(x,z),c= lca(y,z);
71         int ans = (deep[x]+deep[y]-deep[a])+deep[z]-2*deep[lca(a,z)],ansj = a;
72         int u;
73         if((u = (deep[x]+deep[z]-deep[b]+deep[y]-2*deep[lca(b,y)]))<ans)
74         {
75             ans = u;
76             ansj = b;
77         }
78         if((u = (deep[y]+deep[z]-deep[c]+deep[x]-2*deep[lca(c,x)]))<ans)
79         {
80             ans = u;
81             ansj = c;
82         }
83         printf("%d %d\n",ansj,ans);
84     }
85     return 0;
86 }

 

posted @ 2015-09-09 23:09  philippica  阅读(202)  评论(0编辑  收藏  举报