importjava.util.*;publicclassTarjan{staticvoidlca( Node p, ArrayListq ){
MAKE_SET(p);//FIND(p).ancester=p;for( Node i : p.childs){
lca( i, q );
UNION( p, i );
FIND(p).ancester=p;
}
p.checked=true;for( Query query : q ){if( query.p1==p ){if( query.p2.checked ){
query.result=FIND(query.p2);
}
}elseif( query.p2==p ){if( query.p1.checked ){
query.result=FIND(query.p1);
}
}else{continue;
}
}
}staticvoidMAKE_SET( Node p ){
p.ancester=p;
}staticNode FIND( Node p ){
Node r=p;for( ; r.ancester!=r; r=r.ancester );returnr;
}staticvoidUNION( Node p, Node q ){
q.ancester=p;
}publicstaticvoidmain( String args[] ){//create treeNode p[]=newNode[24];
p[0]=newNode(0,null);//rootp[1]=newNode(1,p[0]);
p[2]=newNode(2,p[0]);
p[3]=newNode(3,p[0]);
p[4]=newNode(4,p[1]);
p[5]=newNode(5,p[1]);
p[6]=newNode(6,p[1]);
p[7]=newNode(7,p[2]);
p[8]=newNode(8,p[2]);
p[9]=newNode(9,p[3]);
p[10]=newNode(10,p[3]);
p[11]=newNode(11,p[3]);
p[12]=newNode(12,p[4]);
p[13]=newNode(13,p[4]);
p[14]=newNode(14,p[6]);
p[15]=newNode(15,p[8]);
p[16]=newNode(16,p[10]);
p[17]=newNode(17,p[10]);
p[18]=newNode(18,p[14]);
p[19]=newNode(19,p[14]);
p[20]=newNode(20,p[17]);
p[21]=newNode(21,p[17]);
p[22]=newNode(22,p[17]);
p[23]=newNode(23,p[11]);//make lca queryArrayListq=newArrayList();
q.add(newQuery(p[15], p[19]));
q.add(newQuery(p[21], p[16]));
q.add(newQuery(p[14], p[14]));
q.add(newQuery(p[4], p[23]));
q.add(newQuery(p[23], p[16]));//lcalca( p[0], q );//dump resultsfor( Query item : q ){
System.out.println( item.p1+":"+item.p2+": result is:"+item.result );
}
}
}classNode{publicNode(intid, Node parent ){this.id=id;if( parent!=null){
parent.childs.add(this);
}else{assertthis.id==0;
}this.checked=false;this.ancester=null;this.childs=newArrayList();
}intid;
ArrayListchilds;publicString toString(){return"Node:";
}
Node ancester;//used for lca searchbooleanchecked;//used for lca search}classQuery{publicQuery( Node p1, Node p2 ){assertp1!=null&&p2!=null;this.p1=p1;this.p2=p2;this.result=null;
}
Node p1;
Node p2;
Node result;
}