lca 最近公共祖先
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 最近公共祖先的更多相关文章
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)
Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...
- LCA(最近公共祖先)模板
Tarjan版本 /* gyt Live up to every day */ #pragma comment(linker,"/STACK:1024000000,1024000000&qu ...
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...
- LCA近期公共祖先
LCA近期公共祖先 该分析转之:http://kmplayer.iteye.com/blog/604518 1,并查集+dfs 对整个树进行深度优先遍历.并在遍历的过程中不断地把一些眼下可能查询到的而 ...
- LCA 近期公共祖先 小结
LCA 近期公共祖先 小结 以poj 1330为例.对LCA的3种经常使用的算法进行介绍,分别为 1. 离线tarjan 2. 基于倍增法的LCA 3. 基于RMQ的LCA 1. 离线tarjan / ...
- LCA最近公共祖先 ST+RMQ在线算法
对于一类题目,是一棵树或者森林,有多次查询,求2点间的距离,可以用LCA来解决. 这一类的问题有2中解决方法.第一种就是tarjan的离线算法,还有一中是基于ST算法的在线算法.复杂度都是O( ...
- Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】
一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...
- (转)Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)
基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...
- LCA 最近公共祖先 tarjan离线 总结 结合3个例题
在网上找了一些对tarjan算法解释较好的文章 并加入了自己的理解 LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通 ...
随机推荐
- js获取和设置DOM样式函数cssStyle(类似于jquery的$(elem).css())
如题,相信这个函数百度一搜一大推,但令人匪夷所思的是这些函数都写的“奇形怪状的”,例如http://www.cnblogs.com/windows7/archive/2010/03/30/170064 ...
- 自定义Toast的显示效果
Activity: package com.example.editortoast; import android.app.Activity; import android.os.Bundle; im ...
- 修改后的SQL分页存储过程,利用2分法,支持排序
/****** Object: StoredProcedure [dbo].[sys_Page_v3] Script Date: 08/13/2014 09:32:28 ******/ SET ANS ...
- Oracle中建表空间以及用户
第一步:创建临时表空间 --创建临时表空间-- CREATE TEMPORARY TABLESPACE JSYCCS_TEMP ---'JSYCCS_TEMP'临时表空间名 TEMPFILE 'E ...
- 第九章 管理类型(In .net4.5) 之 继承机制
1. 概述 本章包括 设计和实现接口.创建和使用基类 以及 使用.net类库提供的标准接口. 2. 主要内容 2.1 设计和实现接口 一个接口包含公共的方法.属性.事件.索引器.类和结构都可以实现接口 ...
- 从基础开始,从一个SQLHelper开始
最开始考虑的问题有这三点: 1.Access和SQLServer都要能用. 2.尽量简单,清晰. 3.性能不出大问题. public class SQLHelp { #region 私有域 priva ...
- 《Prism 5.0源码走读》Service Locator Pattern
在Prism Bootstrapper里面取实例的时候使用 ServiceLocator模式,使用的是CommonServiceLocator库 (http://commonservicelocato ...
- DIV指令一般用法
本文最初发表于2015-8-14,是由别的地方迁移过来的 (本文所讲为无符号运算) DIV指令是8086汇编中的除法运算指令,它的结果不是浮点数,而是两个整数:商和余数. 我们来看王爽老师是怎么讲的: ...
- EMVTag系列3《持卡人基本信息数据》
Ø 9F61 持卡人证件号 L:2–26 R(需求):数据应存在,在读应用数据过程中,终端不检查: (PBOC2.0第五部分中规定)芯片中持卡人姓名 5F20与持卡人姓名扩展9F0B只能使用一 ...
- hdu 1195 Open the Lock
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1195 Open the Lock Description Now an emergent task f ...