以poj 1330为例;
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cmath> #include<string> #include<queue> #include<algorithm> #include<stack> #include<cstring> #include<vector> #include<list> #include<set> #include<map> using namespace std; #define LL long long #define pi (4*atan(1.0)) #define eps 1e-8 #define bug(x) cout<<"bug"<<x<<endl; const int N=1e4+10,M=2e6+10,inf=1e9+10; const LL INF=1e18+10,mod=1e9+7; struct edge { int v,next; } edge[N<<1]; int head[N<<1],edg,id,n; /// 树链剖分 int fa[N],dep[N],son[N],siz[N]; // fa父亲,dep深度,son重儿子,siz以该点为子树的节点个数 int a[N],ran[N],top[N],tid[N],du[N]; // tid表示边的标号,top通过重边可以到达最上面的点,ran表示标记tid void init() { memset(son,-1,sizeof(son)); memset(head,-1,sizeof(head)); memset(du,0,sizeof(du)); edg=0; id=0; } void add(int u,int v) { edg++; edge[edg].v=v; edge[edg].next=head[u]; head[u]=edg; } void dfs1(int u,int fath,int deep) { fa[u]=fath; siz[u]=1; dep[u]=deep; for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].v; if(v==fath)continue; dfs1(v,u,deep+1); siz[u]+=siz[v]; if(son[u]==-1||siz[v]>siz[son[u]]) son[u]=v; } } void dfs2(int u,int tp) { tid[u]=++id; top[u]=tp; ran[tid[u]]=u; if(son[u]==-1)return; dfs2(son[u],tp); for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].v; if(v==fa[u])continue; if(v!=son[u]) dfs2(v,v); } } int lca(int l,int r) { while(top[l]!=top[r]) { if(dep[top[l]]<dep[top[r]])swap(l,r); l=fa[top[l]]; } if(dep[l]<dep[r])swap(l,r); return r; } int main() { int T; scanf("%d",&T); while(T--) { init(); int n; scanf("%d",&n); for(int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); du[v]++; } for(int i=1;i<=n;i++) if(!du[i]) { dfs1(i,-1,1); dfs2(i,i); break; } int l,r; scanf("%d%d",&l,&r); printf("%d ",lca(l,r)); } return 0; }