算法笔记

模板:

vector<int>g[N];
vector<int>edge[N];
int anc[][N];
int deep[N];
int h[N];
void dfs(int o,int u,int w)
{
if(u!=o)deep[u]=deep[o]+,h[u]=h[o]+w;
for(int j=;j<g[u].size();j++)
{
if(g[u][j]!=o)
{
anc[][g[u][j]]=u;
for(int i=;i<;i++)anc[i][g[u][j]]=anc[i-][anc[i-][g[u][j]]];
dfs(u,g[u][j],edge[u][j]);
}
}
}
int lca(int u,int v)
{
if(deep[u]<deep[v])swap(u,v);
for(int i=;i>=;i--)if(deep[anc[i][u]]>=deep[v])u=anc[i][u];
if(u==v)return u;
for(int i=;i>=;i--)if(anc[i][u]!=anc[i][v])u=anc[i][u],v=anc[i][v];
return anc[][u];
}
int dis(int u,int v)
{
int l=lca(u,v);
return h[u]+h[v]-*h[l];
}

例题:

1.CODEVS 2370 小机房的树

带权lca

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int INF=0x3f3f3f3f;
const int N=5e4+;
vector<int>g[N];
vector<int>edge[N];
int anc[][N];
int deep[N];
int h[N];
void dfs(int o,int u,int w)
{
if(u!=o)deep[u]=deep[o]+,h[u]=h[o]+w;
for(int j=;j<g[u].size();j++)
{
if(g[u][j]!=o)
{
anc[][g[u][j]]=u;
for(int i=;i<;i++)anc[i][g[u][j]]=anc[i-][anc[i-][g[u][j]]];
dfs(u,g[u][j],edge[u][j]);
}
}
}
int lca(int u,int v)
{
if(deep[u]<deep[v])swap(u,v);
for(int i=;i>=;i--)if(deep[anc[i][u]]>=deep[v])u=anc[i][u];
if(u==v)return u;
for(int i=;i>=;i--)if(anc[i][u]!=anc[i][v])u=anc[i][u],v=anc[i][v];
return anc[][u];
}
int dis(int u,int v)
{
int l=lca(u,v);
return h[u]+h[v]-*h[l];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie();
int n,u,v,c,m;
cin>>n;
for(int i=;i<n-;i++)
{
cin>>u>>v>>c;
g[u].push_back(v);
g[v].push_back(u);
edge[u].push_back(c);
edge[v].push_back(c);
}
cin>>m;
for(int i=;i<;i++)anc[i][]=;
dfs(,,);
while(m--)
{
cin>>u>>v;
cout<<dis(u,v)<<endl;
}
return ;
}

2.CODEVS 1036 商务旅行

普通lca

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls rt<<1,l,m
#define rs rt<<1|1,m+1,r
const int INF=0x3f3f3f3f;
const int N=1e5+;
vector<int>g[N];
int anc[][N];
int deep[N];
void dfs(int o,int u)
{
if(o!=u)deep[u]=deep[o]+;
for(int j=;j<g[u].size();j++)
{
if(o!=g[u][j])
{
anc[][g[u][j]]=u;
for(int i=;i<;i++)anc[i][g[u][j]]=anc[i-][anc[i-][g[u][j]]];
dfs(u,g[u][j]);
}
}
}
int lca(int u,int v)
{
if(deep[u]<deep[v])swap(u,v);
for(int i=;i>=;i--)if(deep[anc[i][u]]>=deep[v])u=anc[i][u];
if(u==v)return u;
for(int i=;i>=;i--)if(anc[i][u]!=anc[i][v])u=anc[i][u],v=anc[i][v];
return anc[][u];
}
int dis(int u,int v)
{
return deep[u]+deep[v]-*deep[lca(u,v)];
}
void init()
{
for(int i=;i<;i++)anc[][]=;
dfs(,);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie();
int n,m;
cin>>n;
for(int i=;i<n;i++)
{
int a,b;
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
init();
cin>>m;
int a,b,ans=;
cin>>a;
for(int i=;i<m;i++)
{
cin>>b;
ans+=dis(a,b);
a=b;
}
cout<<ans<<endl;
return ;
}

3.METO CODE P223 拉力赛

带权lca,当lca(a,b)==a时,韵韵才能参加。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ls rt<<1,l,m
#define rs rt<<1|1,m+1,r
#define pb push_back
const int INF=0x3f3f3f3f;
const int N=1e4+;
vector<int>g[N];
vector<ll>edge[N];
int anc[][N];
int deep[N];
ll h[N];
bool vis[N]={false};
int s;
void dfs(int o,int u,ll w)
{
if(o!=u)deep[u]=deep[o]+,h[u]=h[o]+w;
for(int j=;j<g[u].size();j++)
{
if(g[u][j]!=o)
{
anc[][g[u][j]]=u;
for(int i=;i<;i++)anc[i][g[u][j]]=anc[i-][anc[i-][g[u][j]]];
dfs(u,g[u][j],edge[u][j]);
}
}
}
int lca(int u,int v)
{
if(deep[u]<deep[v])swap(u,v);
for(int i=;i>=;i--)if(deep[anc[i][u]]>=deep[v])u=anc[i][u];
if(u==v)return u;
for(int i=;i>=;i--)if(anc[i][u]!=anc[i][v])u=anc[i][u],v=anc[i][v];
return anc[][u];
}
ll dis(int u,int v)
{
return h[u]+h[v]-*h[lca(u,v)];
}
void init()
{
for(int i=;i<;i++)anc[i][]=;
dfs(,,);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie();
int n,m,a,b;
ll t;
cin>>n>>m;
for(int i=;i<n;i++)
{
cin>>a>>b>>t;
g[a].pb(b);
g[b].pb(a);
edge[a].pb(t);
edge[b].pb(t);
}
init();
int cnt=;
ll ans=;
for(int i=;i<m;i++)
{
int a,b;
cin>>a>>b;
if(lca(a,b)==a)
{
cnt++;
ans+=h[b]-h[a];
}
}
cout<<cnt<<endl;
cout<<ans<<endl;
return ;
}

4.HDU 2586 How far way?

带权lca

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
const int INF=0x3f3f3f3f;
const int N=4e4+;
vector<int>g[N];
vector<int>edge[N];
int deep[N];
int h[N];
int anc[][N];
bool vis[N]={false};
int s=;
void dfs(int o,int u,int w)
{
deep[u]=deep[o]+;
h[u]=h[o]+w;
for(int j=;j<g[u].size();j++)
{
if(g[u][j]!=o)
{
anc[][g[u][j]]=u;
for(int i=;i<;i++)anc[i][g[u][j]]=anc[i-][anc[i-][g[u][j]]];
dfs(u,g[u][j],edge[u][j]);
}
}
}
int lca(int u,int v)
{
if(deep[u]<deep[v])swap(u,v);
for(int i=;i>=;i--)if(deep[anc[i][u]]>=deep[v])u=anc[i][u];
if(u==v)return u;
for(int i=;i>=;i--)if(anc[i][u]!=anc[i][v])u=anc[i][u],v=anc[i][v];
return anc[][u];
}
ll dis(int u,int v)
{
return h[u]+h[v]-*h[lca(u,v)];
}
void init()
{
for(int i=;i<;i++)anc[i][]=;
dfs(,,);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie();
int t;
cin>>t;
while(t--)
{
int n,m,a,b,k;
cin>>n>>m;
for(int i=;i<n;i++)
{
cin>>a>>b>>k;
g[a].pb(b);
g[b].pb(a);
edge[a].pb(k);
edge[b].pb(k);
vis[b]=true;
}
init();
for(int i=;i<m;i++)
{
cin>>a>>b;
cout<<dis(a,b)<<endl;
}
//cout<<endl;
}
return ;
}

5.ZOJ P3195 Design the city

带权lca,三点之间的最短路径公式h[a]+h[b]+h[c]-h[lca(a,b)]-h[lca(a,c)]-h[lca(b,c)]。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
const int INF=0x3f3f3f3f;
const int N=5e4+;
vector<int>g[N];
vector<int>edge[N];
int deep[N];
int h[N];
int anc[][N];
void dfs(int o,int u,int w)
{
if(u!=o)deep[u]=deep[o]+,h[u]=h[o]+w;
for(int j=;j<g[u].size();j++)
{
if(g[u][j]!=o)
{
anc[][g[u][j]]=u;
for(int i=;i<;i++)anc[i][g[u][j]]=anc[i-][anc[i-][g[u][j]]];
dfs(u,g[u][j],edge[u][j]);
}
}
}
int lca(int u,int v)
{
if(deep[u]<deep[v])swap(u,v);
for(int i=;i>=;i--)if(deep[anc[i][u]]>=deep[v])u=anc[i][u];
if(u==v)return u;
for(int i=;i>=;i--)if(anc[i][u]!=anc[i][v])u=anc[i][u],v=anc[i][v];
return anc[][u];
}
int dis(int u,int v)
{
return h[u]+h[v]-*h[lca(u,v)];
}
void init()
{
for(int i=;i<;i++)anc[i][]=;
dfs(,,);
}
int main()
{
int n,q,a,b,c;
bool flag=true;
while(~scanf("%d",&n)&&n)
{
if(flag) flag=false;
else printf("\n");
for(int i=;i<n;i++)g[i].clear(),edge[i].clear();
for(int i=;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
g[a].pb(b);
g[b].pb(a);
edge[a].pb(c);
edge[b].pb(c);
}
init();
scanf("%d",&q);
while(q--)
{
scanf("%d%d%d",&a,&b,&c);
printf("%d\n",h[a]+h[b]+h[c]-h[lca(a,b)]-h[lca(a,c)]-h[lca(b,c)]);
}
}
return ;
}

算法笔记--lca倍增算法的更多相关文章

  1. LCA倍增算法

    LCA 算法是一个技巧性很强的算法. 十分感谢月老提供的模板. 这里我实现LCA是通过倍增,其实就是二进制优化. 任何一个数都可以有2的阶数实现 例如16可以由1 2 4 8组合得到 5可以由1 2 ...

  2. 算法笔记_071:SPFA算法简单介绍(Java)

    目录 1 问题描述 2 解决方案 2.1 具体编码   1 问题描述 何为spfa(Shortest Path Faster Algorithm)算法? spfa算法功能:给定一个加权连通图,选取一个 ...

  3. 算法笔记之KMP算法

    本文是<算法笔记>KMP算法章节的阅读笔记,文中主要内容来源于<算法笔记>.本文主要介绍了next数组.KMP算法及其应用以及对KMP算法的优化. KMP算法主要用于解决字符串 ...

  4. 最近公共祖先 LCA 倍增算法

          树上倍增求LCA LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 ...

  5. POJ 1330 Nearest Common Ancestors (LCA,倍增算法,在线算法)

    /* *********************************************** Author :kuangbin Created Time :2013-9-5 9:45:17 F ...

  6. 算法笔记_066:Kruskal算法详解(Java)

    目录 1 问题描述 2 解决方案 2.1 构造最小生成树示例 2.2 伪码及时间效率分析 2.3 具体编码(最佳时间效率)   1 问题描述 何为Kruskal算法? 该算法功能:求取加权连通图的最小 ...

  7. 算法笔记_054:Prim算法(Java)

    目录 1 问题描述 2 解决方案 2.1 贪心法   1 问题描述 何为Prim算法? 此处引用网友博客中一段介绍(PS:个人感觉网友的这篇博客对于Prim算法讲解的很清楚,本文与之相区别的地方在于具 ...

  8. LCA倍增算法的错误与模板

    先上我原来的错误的代码 type node=^link; link=record num:int64; next:node; end; var fa:..,..] of int64; dep:..] ...

  9. LCA 倍增算法模板

    . #include <cstring> #include <cstdio> #include <cstdlib> #include <algorithm&g ...

随机推荐

  1. js绘制圆形时钟

    纯js制作圆形时钟 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  2. linux mysql安装问题

    1.rpm -qa | grep mysql   //首先检查是否安装了mysql   2.如果安装了,卸载 rpm -e mysql   3\ 下载地址 http://dev.mysql.com/d ...

  3. sql server数字转字符串出现科学计数法

    在从excel往sql server导入数据,电话.编号等数字呈现float类型,然后向b表中insert后(phone为nvarchar)出现科学计数法,解决方法:需将float等数据类型转为标准的 ...

  4. GUN C中的attribute

    GNU C 的一大特色就是__attribute__ 机制.__attribute__ 可以设置函数属性(Function Attribute ).变量属性(Variable Attribute )和 ...

  5. ASIC中的一些库和文件类型

    以下内容均来源于网络: 在进行综合,分析STA时,有几种库类型. NLDM: 非线性线载模型,最基本的dot lib. 电压源模型,cap值是单一值.  在90nm工艺以下,由于晶体管的特性变得很复杂 ...

  6. vue的双向数据绑定原理

    原理. vue是采用数据劫持结合发布者-订阅者模式的方式, 通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回 ...

  7. 简单理解offsetleft、offsetTop、offsetParent

    先来看看offsetParent返回的是什么值 ele.offsetParent返回的是ele元素最近的并且是定位过(relative,absolute)的父元素,如果没有父元素或者是父元素中没有一个 ...

  8. python requests 请求的封装

    #encoding=utf-8import requestsimport jsonclass HttpClient(object):    def __init__(self):        pas ...

  9. Linux服务器---设置服务启动

    设置服务开关 用户可以设置某项服务开机启动或者关闭,有图形界面和命令两种方式 1.图形界面 1)在终端输入命令setup,在弹出的界面选择“系统服务” 2)也可以直接在终端输入命令“ntsysv”,得 ...

  10. 升级到php7相关问题,日请求过亿QQ会员活动平台PHP7升级实践

    升级到php7相关问题,日请求过亿QQ会员活动平台PHP7升级实践 日请求过亿:QQ会员活动平台PHP7升级实践http://mp.weixin.qq.com/s?__biz=MjM5MjAwODM4 ...