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. 一个特别不错的jQuery快捷键插件:js-hotkeys

    这其实不是什么新技术,这个插件在很早前就已经发布了,之前有项目用到,所以分享出来添加方式的例子 jQuery.hotkeys.add('esc',function (){ //执行函数 }); jQu ...

  2. setting菜单界面的形成--未优化

    代码: first_preference.xml: <?xml version="1.0" encoding="utf-8"?> <Prefe ...

  3. Laravel 5 基础(十)- 日期,Mutator 和 Scope

    在我们前面的解决方案中,直接给 published_at 赋值为当前日期实际上是一个临时解决方案,我们需要设定发布日期,可能是未来2天后才发布,让我们修改这个问题. 首先修改控制器: public f ...

  4. JAVA中ArrayList用法

    JAVA中ArrayList用法 2011-07-20 15:02:03|  分类: 计算机专业 |  标签:java  arraylist用法  |举报|字号 订阅     Java学习过程中做题时 ...

  5. 小课堂week14 Google软件测试之道

    读<Google软件测试之道> 在IT领域,Google是一面旗帜,是一家非常善于思考善于尝试的公司.随着面临挑战的不断增大,传统的测试开展方式也越来越力不从心,这本书讲述的就是一次完整的 ...

  6. 我的WPF控件库——KAN.WPF.XCtrl(141105)

    自己开发的WPF控件库,只是初版,有扩展的Button,TextBox,Window.详细参见前几篇博文. WPF自定义控件(一)——Button:http://www.cnblogs.com/Qin ...

  7. 统计工具之QQ图

    正态 QQ 图和普通 QQ 图 分位数-分位数 (QQ) 图是两种分布的分位数相对彼此进行绘制的图.评估数据集是否正态分布,并分别研究两个数据集是否具有相似的分布. 如何构建正态 QQ 图 首先,数据 ...

  8. .NET开源工作流RoadFlow-流程设计-流程步骤设置-基本设置

    流程属性设置完成后点击确定之后,即可进行流程步骤设置了. 点击工具栏上的步骤按钮,即可添加一个新步骤. 在新步骤图形上双击即可弹出该步骤相应属性设置框. 步骤ID:系统自动为该步骤生成的唯一ID. 步 ...

  9. [JAVA][RCP] Eclipse4/RCP/Lifecycle

    E4AP provides two levels of lifecycles, for contributions and for the application. Contents [hide]  ...

  10. Helloworld模块之内核makefile详解

    Hello World 模块以及对应的内核makefile详解 hello.c: #include <linux/module.h> //所有模块都需要的头文件 #include < ...