山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

bzoj 1787 [Ahoi2008]Meet 紧急集合(1832 [AHOI2008]聚会)

1787: [Ahoi2008]Meet 紧急集合

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

 

【思路】

       Lca。

       求出三点之间的lca,会出现两个点相同的情况,集合点为另外一个点。

 

【代码】

 1 /**************************************************************
 2     Problem: 1787
 3     User: hahalidaxin2
 4     Language: C++
 5     Result: Accepted
 6     Time:3716 ms
 7     Memory:65216 kb
 8 ****************************************************************/
 9  
10 #include<cstdio>
11 #include<cstring>
12 #include<queue>
13 #include<vector>
14 #include<iostream>
15 using namespace std;
16   
17 const int maxn = 500000+10;
18 const int maxd = 19;
19   
20 struct Edge{ int u,v;
21 };
22 vector<int> G[maxn];
23 vector<Edge> es;
24   
25 int d[maxn];
26 int p[maxn][maxd];
27   
28 void addedge(int u,int v) {
29     es.push_back((Edge){u,v});
30     int m=es.size(); G[u].push_back(m-1);
31 }
32 void dfs(int u,int fa) { 
33     for(int i=1;i<=maxd;i++) {       //构造倍增数组 
34         if(d[u]<(1<<i)) break;
35         p[u][i]=p[p[u][i-1]][i-1];
36     }
37     for(int i=0;i<G[u].size();i++) {
38         Edge e=es[G[u][i]]; int v=e.v;
39         if(v!=fa)
40             d[v]=d[u]+1 , p[v][0]=u , dfs(v,u);
41     }
42 }
43 int lca(int u,int v) {
44     if(d[v]>d[u]) swap(u,v);
45     int dep=d[u]-d[v];
46     for(int i=0;i<maxd;i++)
47         if((1<<i)&dep) u=p[u][i]; 
48     if(u==v) return u;
49     for(int i=maxd-1;i>=0;i--)
50         if(p[u][i]!=p[v][i])
51             u=p[u][i] , v=p[v][i];
52     return p[u][0];
53 }
54 int dist(int x,int y) { return d[x]+d[y]-(d[lca(x,y)]<<1); }
55 int n,m;
56   
57 void read(int& x) {
58     char c=getchar(); 
59     while(!isdigit(c)) c=getchar();
60     x=0;
61     while(isdigit(c))
62         x=x*10+c-'0' , c=getchar();
63 }
64 int main() {
65     read(n),read(m);
66     int u,v;
67     for(int i=0;i<n-1;i++) {
68         read(u),read(v);
69         addedge(u,v); addedge(v,u);
70     }
71     dfs(n>>1,-1);
72     int a,b,c,lab,lac,lbc,s;
73     while(m--) {
74         read(a),read(b),read(c);
75         lab=lca(a,b),lac=lca(a,c),lbc=lca(b,c);
76         if(lab==lac) s=lbc;
77         else if(lab==lbc) s=lac;
78         else s=lab;
79         printf("%d %d\n",s,dist(a,s)+dist(b,s)+dist(c,s));
80     }
81     return 0;
82 }

 

posted on 2016-01-03 17:01  hahalidaxin  阅读(232)  评论(0编辑  收藏  举报