码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ-1787: [Ahoi2008]Meet 紧急集合 (LCA)

时间:2017-10-24 21:01:53      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:out   log   bre   type   lca   swap   print   get   content   

1787: [Ahoi2008]Meet 紧急集合

Time Limit: 20 Sec  Memory Limit: 162 MB
Submit: 3445  Solved: 1565
[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中的深度大的点作为集合点,看了Po姐的感觉她貌似做繁了??还是我的思路错了??于是去看hzwer的,hzwer给了两个,其中有一个是选取除了两个相同的LCA的另一个LCA作为集合点,思忖了一下发现跟我的思路本质上是一样的
如图:技术分享这是一般的情况如果选取a点为集合点的话将会有两个人x,y走ab这条路径,但是如果选取b点为集合点的话只有一个人z走ab这条路径,hzwer的两个lca相同的情况就相当于是告诉你了a是x,y的祖先的祖先
 
然而laj貌似忘了LCA怎么写了 _(:зゝ∠)_ 第一次交因为存边的数组大小忘记×2了还T了一次 _(:зゝ∠)_
 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 typedef long long LL;
 4 const int MAX=5e5+5;
 5 int n,m;
 6 int tot,head[MAX],adj[MAX<<1],next[MAX<<1];
 7 int fa[MAX][21],deep[MAX];
 8 bool vis[MAX];
 9 inline int read(){
10     int an=0,x=1;char c=getchar();
11     while (c<0 || c>9) {if (c==-) x=-1;c=getchar();}
12     while (c>=0 && c<=9) {an=(an<<3)+(an<<1)+c-0;c=getchar();}
13     return an;
14 }
15 void addedge(int u,int v){
16     tot++,adj[tot]=v,next[tot]=head[u],head[u]=tot;
17 }
18 void dfs(int x){
19     vis[x]=true;
20     int i,j;
21     for (i=1;i<=20;i++){
22         if (deep[x]<(1<<i)) break;
23         fa[x][i]=fa[fa[x][i-1]][i-1];
24     }
25     for (i=head[x];i;i=next[i]){
26         if (!vis[adj[i]]){
27             deep[adj[i]]=deep[x]+1;
28             fa[adj[i]][0]=x;
29             dfs(adj[i]);
30         }
31     }
32 }
33 int lca(int x,int y){
34     int i,j;
35     if (deep[x]<deep[y]) swap(x,y);
36     int dd=deep[x]-deep[y];
37     for (i=20;i>=0;i--)
38         if (dd&(1<<i)) x=fa[x][i];
39     for (i=20;i>=0;i--)
40         if (fa[x][i]!=fa[y][i]){
41             x=fa[x][i],y=fa[y][i];
42         }
43     return x==y?x:fa[x][0];
44 }
45 inline int dist(int x,int y,int z){return deep[x]+deep[y]-2*deep[z];}
46 int main(){
47     freopen ("emer.in","r",stdin);freopen ("emer.out","w",stdout);
48     int i,j,u,v,x,y,z,xy,yz,zx,dis;
49     n=read(),m=read();
50     for (i=1;i<n;i++){
51         u=read(),v=read();
52         addedge(u,v),addedge(v,u);
53     }
54     dfs(1);
55     for (i=1;i<=m;i++){
56         x=read(),y=read(),z=read();
57         dis=0;
58         xy=lca(x,y),zx=lca(x,z),yz=lca(y,z);
59         if (xy==zx){
60             printf("%d ",yz);
61             dis=dist(y,yz,yz)+dist(z,yz,yz)+dist(yz,x,xy);
62             printf("%d\n",dis);
63         }
64         else if (xy==yz){
65             printf("%d ",zx);
66             dis=dist(zx,x,zx)+dist(z,zx,zx)+dist(zx,y,xy);
67             printf("%d\n",dis);
68         }
69         else if (zx==yz){
70             printf("%d ",xy);
71             dis=dist(xy,x,xy)+dist(y,xy,xy)+dist(xy,z,zx);
72             printf("%d\n",dis);
73         }
74     }
75     return 0;
76 }

 

BZOJ-1787: [Ahoi2008]Meet 紧急集合 (LCA)

标签:out   log   bre   type   lca   swap   print   get   content   

原文地址:http://www.cnblogs.com/keximeiruguo/p/7725270.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!