LCA的一道比较有意思的题
目的是找到三个点的最近点
LCA即可解决
分别找到每两个边的lca
其中肯定有两个相同的
那么另一个就是所求点
哈哈哈
20秒的题
跑了17秒
哈哈
我发现了一道两百秒的题
一会写个死循环
测评机三分钟被我独占
美滋滋
哈哈
我好坏
开玩笑的
我才不干那种没道德的事
哈哈
tarjan算法真的好有意思
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e6;
int ver[N],head[N],Next[N],v[N],fa[N],d[N],tot=0;
vector<int> query_id[N],query[N];
struct Plant{
int x,y;
}ans[N];
void add(int x,int y){
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
void add_qurery(int x,int y,int id){
if(x==y) ans[id].x=x,ans[id].y=0;
else{
query[x].push_back(y);
query[y].push_back(x);
query_id[x].push_back(id);
query_id[y].push_back(id);
}
}
int get(int x){
if(x==fa[x]) return x;
return fa[x]=get(fa[x]);
}
void tarjan(int x){
v[x]=1;
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(v[y]) continue;
d[y]=d[x]+1;
tarjan(y);
fa[y]=x;
}
for(int i=0;i<query[x].size();++i){
int y=query[x][i],id=query_id[x][i];
if(v[y]==2){
int lca=get(y);
ans[id].x=lca;
ans[id].y=d[x]+d[y]-2*d[lca];
}
}
v[x]=2;
}
void F(Plant a,Plant b,Plant c,int &x,int &y){
if(a.x==b.x){
x=c.x;
y=(a.y+b.y+c.y)/2;
return;
}
if(a.x==c.x){
x=b.x;
y=(a.y+b.y+c.y)/2;
return;
}
if(b.x==c.x){
x=a.x;
y=(a.y+b.y+c.y)/2;
return;
}
}
int main(){
int n,m,x,y,z;
cin>>n>>m;
for(int i=1;i<n;++i){
cin>>x>>y;
add(x,y);add(y,x);
}
for(int i=1;i<=n;++i) fa[i]=i;
for(int i=0;i<m;++i){
cin>>x>>y>>z;
add_qurery(x,y,i*3+1);
add_qurery(x,z,i*3+2);
add_qurery(y,z,i*3+3);
}
tarjan(1);
for(int i=0;i<m;++i){
F(ans[i*3+1],ans[i*3+2],ans[i*3+3],x,y);
cout<<x<<" "<<y<<endl;
}
}