[Ahoi2008]Meet 紧急集合
Posted kcfzyhq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Ahoi2008]Meet 紧急集合相关的知识,希望对你有一定的参考价值。
1787: [Ahoi2008]Meet 紧急集合
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 3892 Solved: 1771
[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
【代码】
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> using std::swap; const int maxn=500010,maxm=500010; int ver[maxm<<1],nxt[maxm<<1],head[maxn],en,d[maxn],f[maxn][20],len; inline void AddEdge(int from,int to) { ver[++en]=to,nxt[en]=head[from],head[from]=en; } void dfs(int x,int fa) { d[x]=d[fa]+1; for(int i=head[x]; i; i=nxt[i]) { int y=ver[i]; if(d[y])continue; f[y][0]=x; for(int j=1; j<=len; j++)f[y][j]=f[f[y][j-1]][j-1]; dfs(y,x); } } int LCA(int x,int y) { if(d[x]>d[y])swap(x,y); for(int i=len; i>=0; i--) if(d[f[y][i]]>=d[x])y=f[y][i]; if(x==y)return x; for(int i=len; i>=0; i--) if(f[y][i]!=f[x][i])y=f[y][i],x=f[x][i]; return f[x][0]; } inline int cal(int a,int b){ int t=LCA(a,b); return d[a]+d[b]-2*d[t]; } int main() { en=0; memset(head,0,sizeof(head)); memset(d,0,sizeof(d)); int n,m,x,y,z; scanf("%d%d",&n,&m); len=(int)(log(n)/log(2))+1; for(int i=1; i<n; i++) { scanf("%d%d",&x,&y); AddEdge(x,y); AddEdge(y,x); } dfs(1,0); for(int i=1; i<=m; i++) { scanf("%d%d%d",&x,&y,&z); int a=LCA(x,y),b=LCA(x,z),c=LCA(y,z),g; if(a==b) g=c; else if(a==c) g=b; else g=a; printf("%d %d\\n",g,cal(x,g)+cal(y,g)+cal(z,g)); } return 0; }
以上是关于[Ahoi2008]Meet 紧急集合的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 1787: [Ahoi2008]Meet 紧急集合
BZOJ-1787: [Ahoi2008]Meet 紧急集合 (LCA)
[bzoj1787][Ahoi2008]Meet 紧急集合(lca)