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

1787: [Ahoi2008]Meet 紧急集合

Description

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

Input

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

Output

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

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

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

题解:求出两两lca,其中有两个相同,答案则为另一个,参考HZWer.

///

#include<bits/stdc++.h>
using namespace std;
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){
if(ch=='-')f=-;ch=getchar();
}
while(ch>=''&&ch<=''){
x=x*+ch-'';ch=getchar();
}return x*f;
}
//****************************************
const int N=;
#define mod 1000000007
#define inf 1000000007
int n,m,head[N],t,vis[N],deep[N],fa[N][];
struct ss {
int to,next;
}e[N*];
void add(int u,int v) {
e[t].next=head[u];e[t].to=v;head[u]=t++;
}
void init() {
t=;mem(head);mem(vis);mem(fa);mem(deep);
}
void dfs(int x) {
vis[x]=;
for (int i=; i<= ;i++) {
if(deep[x]<(<<i)) break;
fa[x][i] = fa[fa[x][i-]][i-];
}
for (int i=head[x];i;i=e[i].next) {
if(vis[e[i].to]) continue;
deep[e[i].to]=deep[x]+;
fa[e[i].to][]=x;
dfs(e[i].to);
}
}
int RMQ_LCA(int x,int y) {
if(deep[x]<deep[y]) swap(x,y);
int d=deep[x]-deep[y];
for (int i=; i<= ;i++)
if((<<i)&d) x=fa[x][i];
for (int i=; i>= ;i--) {
if(fa[x][i]!=fa[y][i]) {
x=fa[x][i];y=fa[y][i];
}
}
if(x==y) return x;
else return fa[x][];
}
int Dis_LCA(int x,int y) {
int LCA= RMQ_LCA(x,y);
return (deep[x]+deep[y]-*deep[LCA]);
}
int cal(int x,int y,int z) {
int A;
int L1=RMQ_LCA(x,y);
int L2=RMQ_LCA(y,z);
int L3=RMQ_LCA(x,z);
if(L1==L2) {
A=L3;
}
else if(L2==L3) {
A=L1;
}
else A=L2;
int anss=Dis_LCA(x,A)+Dis_LCA(y,A)+Dis_LCA(z,A);
printf("%d %d\n",A,anss);
//cout<<A<<" "<<anss<<endl;
}
int main() {
scanf("%d%d",&n,&m);
init();
for(int i=;i<n;i++) {
int u,v;
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dfs();
for(int i=;i<=m;i++) {
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
cal(a,b,c);
} return ;
}

代码

上一篇:解决php使用ZipArchive解压时中文乱码问题


下一篇:nodejs 更改项目端口号的 方法