最近公共祖先问题,求的是中两个节点的最近公共祖先。使用了一个带并查集的离线算法。
#include <stdio.h>

const int LEN = 10005;

int p[LEN];

void make ( int n )


{
for ( int i=0; i<n; i++ )

{
p[i] = -1;
}
}

int find ( int a )


{

if ( p[a] < 0 )

{
return a;
}
int r = find ( p[a] );
p[a] = r;

return r;
}

void un ( int a, int b )


{

int ra = find ( a );
int rb = find ( b );

p[rb] = ra;
}

struct


{

int c;/**//*记录结点的入度*/

int last;/**//*记录最后一个节点的地址*/
int next;

}tab[LEN];/**//*邻接链表头,记录最后一个节点的地址*/
typedef struct


{
int num;
int next;
}type;
type node[LEN*2];

int next1; /**//*下一个可以使用的位置*/

void initm ( int n )


{

next1 = 0;
for ( int i=0; i<n; i++ )

{
tab[i].c = 0;
tab[i].last = -1;
tab[i].next = -1;
}
}


void adde ( int b, int e )/**//*增加一条边*/


{

node[next1].num = e;
node[next1].next = -1;
if ( tab[b].next >= 0 )

{
node[ tab[b].last ].next = next1;
}
else

{
tab[b].next = next1;
}
tab[b].last = next1;
tab[e].c ++;
next1 ++;
}

struct


{
int next;
int last;
}que[LEN];
type q[LEN*2];
int next2;

void initq ( int n )


{

next2 = 0;
for ( int i=0; i<n; i++ )

{
que[i].last = -1;
que[i].next = -1;
}
}


void addq ( int b, int e )/**//*增加一条边*/


{

q[next2].num = e;
q[next2].next = -1;
if ( que[b].next >= 0 )

{
q[ que[b].last ].next = next2;
}
else

{
que[b].next = next2;
}
que[b].last = next2;
next2 ++;
}

int color[LEN];

void initc ( int n )


{

for ( int i=0; i<n; i++ )

{
color[i] = 0;
}
}

void lca ( int p )


{

for ( int i=tab[p].next; i!=-1; i=node[i].next )

{
lca ( node[i].num );
un ( p, node[i].num );
}

for ( i=que[p].next; i!=-1; i=q[i].next )

{
if ( color[ q[i].num ] )

{
printf ( "%d\n", find ( q[i].num ) + 1 );
}
}
color[p] = 1;
}

int main ()


{

int t;
int n;
int b, e;

scanf ( "%d", &t );
while ( t -- )

{
scanf ( "%d", &n );

initm ( n );
for ( int i=0; i<n-1; i++ )

{
scanf ( "%d%d", &b, &e );
adde ( b-1, e-1 );
}

initq ( n );
scanf ( "%d%d", &b, &e );
addq ( b-1, e-1 );
addq ( e-1, b-1 );


initc ( n );/**//*初始化颜色*/
make ( n );

for ( i=0; i<n; i++ )

{
if ( ! tab[i].c )

{
break;
}
}
lca ( i );

}
return 0;
}

地址:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1330