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),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点.也就是说,在两个点通 ...
随机推荐
- Linux安装配置php环境的方法
本文实例讲述了Linux安装配置php环境的方法.分享给大家供大家参考,具体如下: 1.获取安装文件: http://www.php.net/downloads.php php-5.3.8.tar.g ...
- 在Spark中使用Kryo序列化
spark序列化 对于优化<网络性能>极为重要,将RDD以序列化格式来保存减少内存占用. spark.serializer=org.apache.spark.serializer.Jav ...
- WordPress 非插件实现拦截无中文留言
Some Chinese Please 插件可以拦截不带中文字的留言,之前本博客一直在用效果不错,不写入数据库,可有效地减少 spam 对服务器的无谓使用,其实可以将插件简化一下,直接用代码实现.将下 ...
- php数组去重复代码
php数组去重复数据示例,有时候获得的php数组中总是出现value重复的,使用下面的方法就可以去掉重复数据 以数字开头的重复数据如: Array ( [0] => 100 [k1] =&g ...
- WordPress 主题开发 - (八) Head模板 待翻译
THE WORDPRESS THEME HEADER TEMPLATE Now we get into the nitty-gritty: building up your header.php an ...
- mybatis动态sql中的trim标签的使用(转)
trim标记是一个格式化的标记,可以完成set或者是where标记的功能,如下代码: 1. select * from user <trim prefix="WHERE" p ...
- angularJS通过post方法下载excel文件
最近工作中遇到,要使用angularJS的post方法来下载excel的情况.网上找到一个帖子:http://stackoverflow.com/questions/22447952/angularj ...
- delphi 博客地址收藏
博客地址: Delphi XE5 for Android系列,值得入门者一读http://www.cnblogs.com/ChinaEHR/p/3346867.html http://hi.baidu ...
- WPF优化体验<一>
最近将一个开发和维护了五年的一个Winform项目进行重构,考虑到最近很流行将用户体验挂在嘴上,于是采用了WPF技术,希望能在外观和体验上有一个全新的效果. 以前使用Winform的时候内存控制得不错 ...
- 使用Telerik控件搭建Doubanfm频道部分
今天感觉好累啊..还是坚持记录下. 收集的API: https://github.com/HakurouKen/douban.fm-api https://github.com/zonyitoo/do ...