BZOJ-1787: [Ahoi2008]Meet 紧急集合 (LCA)
Posted 可惜没如果=_=
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ-1787: [Ahoi2008]Meet 紧急集合 (LCA)相关的知识,希望对你有一定的参考价值。
1787: [Ahoi2008]Meet 紧急集合
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 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
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)的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ-1787: [Ahoi2008]Meet 紧急集合 (LCA)
BZOJ——1787: [Ahoi2008]Meet 紧急集合