http://poj.org/problem?id=1330

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
const int inf=0x3f3f3f3f;
class LCA { ///最近公共祖先 build_o(n*logn) query_o(1)
typedef int typec;///边权的类型
static const int ME=2e4+;///边的个数
static const int MV=1e4+;///点的个数
static const int MR=MV<<;///rmq的个数
struct E {
int v,next;
typec w;
} e[ME];
int le,head[MV],H[MV],dex[MR],aa[MR],bb[MR],raa[MR][],rbb[MR][],Index;
typec dist[MV];
void init_dex() {
dex[]=-;
for(int i=; i<MR; i++) {
dex[i]=dex[i>>]+;
}
}
void dfs(int u,int fa,int level) {
aa[Index]=u;
bb[Index++]=level;
for(int i=head[u]; ~i; i=e[i].next) {
int v=e[i].v;
if(v==fa) continue;
dist[v]=dist[u]+e[i].w;
dfs(v,u,level+);
aa[Index]=u;
bb[Index++]=level;
}
}
public:
LCA() { init_dex();};
void init() {
le=Index=;
mt(head,-);
}
void add(int u,int v,typec w) {
e[le].v=v;
e[le].w=w;
e[le].next=head[u];
head[u]=le++;
}
void build(int root) {
dist[root]=;
dfs(root,-,);
mt(H,-);
mt(rbb,0x3f);
for(int i=; i<Index; i++) {
int tmp=aa[i];
if(H[tmp]==-) H[tmp]=i;
rbb[i][]=bb[i];
raa[i][]=aa[i];
}
for(int i=; (<<i)<=Index; i++) {
for(int j=; j+(<<i)<Index; j++) {
int next=j+(<<(i-));
if(rbb[j][i-]<=rbb[next][i-]) {
rbb[j][i]=rbb[j][i-];
raa[j][i]=raa[j][i-];
} else {
rbb[j][i]=rbb[next][i-];
raa[j][i]=raa[next][i-];
}
}
}
}
int query(int l,int r) {
l=H[l];
r=H[r];
if(l>r) swap(l,r);
int p=dex[r-l+];
r-=(<<p)-;
return rbb[l][p]<=rbb[r][p]?raa[l][p]:raa[r][p];
}
typec getdist(int l,int r) {
return dist[l]+dist[r]-*dist[query(l,r)];
}
} gx; const int M=1e4+;
int du[M];
int main() {
int t,n,u,v;
while(~scanf("%d",&t)) {
while(t--) {
scanf("%d",&n);
gx.init();
mt(du,);
for(int i=; i<n; i++) {
scanf("%d%d",&u,&v);
du[v]++;
gx.add(u,v,);
gx.add(v,u,);
}
int rt=;
for(int i=; i<=n; i++) {
if(du[i]==) {
rt=i;
break;
}
}
gx.build(rt);
scanf("%d%d",&u,&v);
printf("%d\n",gx.query(u,v));
}
}
return ;
}

http://poj.org/problem?id=1470

 #include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
int getint(){
int res=;
char tmp;
while(!isdigit(tmp=getchar()));
do{
res=(res<<)+(res<<)+tmp-'';
}while(isdigit(tmp=getchar()));
return res;
} class LCA { ///最近公共祖先 build_o(n*logn) query_o(1)
typedef int typec;///边权的类型
static const int ME=2e3+;///边的个数
static const int MV=1e3+;///点的个数
static const int MR=MV<<;///rmq的个数
struct E {
int v,next;
typec w;
} e[ME];
int le,head[MV],H[MV],dex[MR],aa[MR],bb[MR],raa[MR][],rbb[MR][],Index;
typec dist[MV];
void init_dex() {
dex[]=-;
for(int i=; i<MR; i++) {
dex[i]=dex[i>>]+;
}
}
void dfs(int u,int fa,int level) {
aa[Index]=u;
bb[Index++]=level;
for(int i=head[u]; ~i; i=e[i].next) {
int v=e[i].v;
if(v==fa) continue;
dist[v]=dist[u]+e[i].w;
dfs(v,u,level+);
aa[Index]=u;
bb[Index++]=level;
}
}
public:
LCA() {
init_dex();
};
void init() {
le=Index=;
mt(head,-);
}
void add(int u,int v,typec w) {
e[le].v=v;
e[le].w=w;
e[le].next=head[u];
head[u]=le++;
}
void build(int root) {///传入树根
dist[root]=;
dfs(root,-,);
mt(H,-);
mt(rbb,0x3f);
for(int i=; i<Index; i++) {
int tmp=aa[i];
if(H[tmp]==-) H[tmp]=i;
rbb[i][]=bb[i];
raa[i][]=aa[i];
}
for(int i=; (<<i)<=Index; i++) {
for(int j=; j+(<<i)<Index; j++) {
int next=j+(<<(i-));
if(rbb[j][i-]<=rbb[next][i-]) {
rbb[j][i]=rbb[j][i-];
raa[j][i]=raa[j][i-];
} else {
rbb[j][i]=rbb[next][i-];
raa[j][i]=raa[next][i-];
}
}
}
}
int query(int l,int r) {///查lca
l=H[l];
r=H[r];
if(l>r) swap(l,r);
int p=dex[r-l+];
r-=(<<p)-;
return rbb[l][p]<=rbb[r][p]?raa[l][p]:raa[r][p];
}
typec getdist(int l,int r) {///查两点最短距离
return dist[l]+dist[r]-*dist[query(l,r)];
}
} g; int ans[];
int du[];
int main(){
int n,m,u,v;
while(~scanf("%d",&n)){
g.init();
mt(du,);
for(int i=;i<n;i++){
u=getint();
m=getint();
while(m--){
v=getint();
du[v]++;
g.add(u,v,);
g.add(v,u,);
}
}
int root=;
for(int i=;i<=n;i++){
if(du[i]==){
root=i;
break;
}
}
g.build(root);
m=getint();
mt(ans,);
// printf("m=%d\n",m);
for(int i=;i<m;i++){
u=getint();
v=getint();
// printf("u=%d v=%d\n",u,v);
ans[g.query(u,v)]++;
// printf("m=%d\n",m);
}
// puts("out");
for(int i=;i<=n;i++){
if(ans[i]){
printf("%d:%d\n",i,ans[i]);
}
} }
return ;
}

http://poj.org/problem?id=1986

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define mt(a,b) memset(a,b,sizeof(a))
using namespace std;
const int inf=0x3f3f3f3f;
//const int M=100010;
class LCA { ///最近公共祖先 build_o(n*logn) query_o(1)
typedef int typec;///边权的类型
static const int ME=2e5+;///边的个数
static const int MV=1e5+;///点的个数
static const int MR=MV<<;///rmq的个数
struct E {
int v,next;
typec w;
} e[ME];
int le,head[MV],H[MV],dex[MR],aa[MR],bb[MR],raa[MR][],rbb[MR][],Index;
typec dist[MV];
void init_dex() {
dex[]=-;
for(int i=; i<MR; i++) {
dex[i]=dex[i>>]+;
}
}
void dfs(int u,int fa,int level) {
aa[Index]=u;
bb[Index++]=level;
for(int i=head[u]; ~i; i=e[i].next) {
int v=e[i].v;
if(v==fa) continue;
dist[v]=dist[u]+e[i].w;
dfs(v,u,level+);
aa[Index]=u;
bb[Index++]=level;
}
}
public:
LCA() {
init_dex();
};
void init() {
le=Index=;
mt(head,-);
}
void add(int u,int v,typec w) {
e[le].v=v;
e[le].w=w;
e[le].next=head[u];
head[u]=le++;
}
void build(int root) {///传入树根
dist[root]=;
dfs(root,-,);
mt(H,-);
mt(rbb,0x3f);
for(int i=; i<Index; i++) {
int tmp=aa[i];
if(H[tmp]==-) H[tmp]=i;
rbb[i][]=bb[i];
raa[i][]=aa[i];
}
for(int i=; (<<i)<=Index; i++) {
for(int j=; j+(<<i)<Index; j++) {
int next=j+(<<(i-));
if(rbb[j][i-]<=rbb[next][i-]) {
rbb[j][i]=rbb[j][i-];
raa[j][i]=raa[j][i-];
} else {
rbb[j][i]=rbb[next][i-];
raa[j][i]=raa[next][i-];
}
}
}
}
int query(int l,int r) {///查lca
l=H[l];
r=H[r];
if(l>r) swap(l,r);
int p=dex[r-l+];
r-=(<<p)-;
return rbb[l][p]<=rbb[r][p]?raa[l][p]:raa[r][p];
}
typec getdist(int l,int r) {///查两点最短距离
return dist[l]+dist[r]-*dist[query(l,r)];
}
} gx; #include<cctype>
int getint(){
int res=;
char tmp;
while(!isdigit(tmp=getchar()));
do{
res=(res<<)+(res<<)+tmp-'';
}while(isdigit(tmp=getchar()));
return res;
}
int main(){
int n,m,x,y,z;
char op[];
while(~scanf("%d%d",&n,&m)){
gx.init();
while(m--){
// scanf("%d%d%d%s",&x,&y,&z,op);
x=getint();
y=getint();
z=getint();
gx.add(x,y,z);
gx.add(y,x,z);
}
// scanf("%d",&m);
m=getint();
gx.build();
while(m--){
// scanf("%d%d",&x,&y);
x=getint();
y=getint();
printf("%d\n",gx.getdist(x,y));
}
}
return ;
}

end

lca 最近公共祖先的更多相关文章

  1. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)

    Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...

  2. LCA(最近公共祖先)模板

    Tarjan版本 /* gyt Live up to every day */ #pragma comment(linker,"/STACK:1024000000,1024000000&qu ...

  3. CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )

    CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...

  4. LCA近期公共祖先

    LCA近期公共祖先 该分析转之:http://kmplayer.iteye.com/blog/604518 1,并查集+dfs 对整个树进行深度优先遍历.并在遍历的过程中不断地把一些眼下可能查询到的而 ...

  5. LCA 近期公共祖先 小结

    LCA 近期公共祖先 小结 以poj 1330为例.对LCA的3种经常使用的算法进行介绍,分别为 1. 离线tarjan 2. 基于倍增法的LCA 3. 基于RMQ的LCA 1. 离线tarjan / ...

  6. LCA最近公共祖先 ST+RMQ在线算法

    对于一类题目,是一棵树或者森林,有多次查询,求2点间的距离,可以用LCA来解决.     这一类的问题有2中解决方法.第一种就是tarjan的离线算法,还有一中是基于ST算法的在线算法.复杂度都是O( ...

  7. Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】

    一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...

  8. (转)Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)

    基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...

  9. LCA 最近公共祖先 tarjan离线 总结 结合3个例题

    在网上找了一些对tarjan算法解释较好的文章 并加入了自己的理解 LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通 ...

随机推荐

  1. js获取和设置DOM样式函数cssStyle(类似于jquery的$(elem).css())

    如题,相信这个函数百度一搜一大推,但令人匪夷所思的是这些函数都写的“奇形怪状的”,例如http://www.cnblogs.com/windows7/archive/2010/03/30/170064 ...

  2. 自定义Toast的显示效果

    Activity: package com.example.editortoast; import android.app.Activity; import android.os.Bundle; im ...

  3. 修改后的SQL分页存储过程,利用2分法,支持排序

    /****** Object: StoredProcedure [dbo].[sys_Page_v3] Script Date: 08/13/2014 09:32:28 ******/ SET ANS ...

  4. Oracle中建表空间以及用户

    第一步:创建临时表空间   --创建临时表空间-- CREATE TEMPORARY TABLESPACE JSYCCS_TEMP ---'JSYCCS_TEMP'临时表空间名 TEMPFILE 'E ...

  5. 第九章 管理类型(In .net4.5) 之 继承机制

    1. 概述 本章包括 设计和实现接口.创建和使用基类 以及 使用.net类库提供的标准接口. 2. 主要内容 2.1 设计和实现接口 一个接口包含公共的方法.属性.事件.索引器.类和结构都可以实现接口 ...

  6. 从基础开始,从一个SQLHelper开始

    最开始考虑的问题有这三点: 1.Access和SQLServer都要能用. 2.尽量简单,清晰. 3.性能不出大问题. public class SQLHelp { #region 私有域 priva ...

  7. 《Prism 5.0源码走读》Service Locator Pattern

    在Prism Bootstrapper里面取实例的时候使用 ServiceLocator模式,使用的是CommonServiceLocator库 (http://commonservicelocato ...

  8. DIV指令一般用法

    本文最初发表于2015-8-14,是由别的地方迁移过来的 (本文所讲为无符号运算) DIV指令是8086汇编中的除法运算指令,它的结果不是浮点数,而是两个整数:商和余数. 我们来看王爽老师是怎么讲的: ...

  9. EMVTag系列3《持卡人基本信息数据》

    Ø  9F61    持卡人证件号 L:2–26 R(需求):数据应存在,在读应用数据过程中,终端不检查: (PBOC2.0第五部分中规定)芯片中持卡人姓名 5F20与持卡人姓名扩展9F0B只能使用一 ...

  10. hdu 1195 Open the Lock

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1195 Open the Lock Description Now an emergent task f ...