算法笔记

模板:

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. C# 多线程,new ThreadStart(方法)中的方法如果有参数,该怎么写

    using System; using System.Threading; public class Work { public static void Main() { // Start a thr ...

  2. 基于Axis1.4的webservice接口开发(代码开发)

    基于Axis1.4的webservice接口开发(代码开发) 一.开发环境: 我的开发环境是MyEclipse 2015+Apache-Tomcat-8.0.21. 二.代码开发: 1.新建一个Web ...

  3. aspose 小记

    /// <summary> /// 定位书签替换值 /// </summary> /// <param name="documentBuilder"& ...

  4. Centos 更改系统时间

    .date //查看本地 .hwclock --show //查看硬件的时间 .如果硬件的时间是对不上,那就对硬件的时间进行修改 .hwclock --set --date '2222-22-22 2 ...

  5. Mysql管理工具 SqlYog快捷键大全

    Ctrl+M   创建一个新的连接Ctrl+N   使用当前设置新建连接Ctrl+F4   断开当前连接 对象浏览器F5   刷新对象浏览器(默认)Ctrl+B   设置焦点于对象浏览器 SQL 窗口 ...

  6. troubleshooting-sqoop mysql导入hive 报:GC overhead limit exceeded

    Halting due to Out Of Memory Error...18/09/13 21:42:17 INFO mapreduce.Job: Task Id : attempt_1536756 ...

  7. 《网络对抗》拓展:注入shellcode

    实践三 知识要求: shellcode:指溢出后执行的能开启系统shell的代码.但是在缓冲区溢出攻击时,也可以将整个触发缓冲区溢出攻击过程的代码统称为shellcode,因此可以将shellcode ...

  8. Postgresql数据库实用命令

    Postgresql 命令 pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start 启动数据库 cr ...

  9. [noip模拟题]排队

    [问题描述] 小sin所在的班有n名同学,正准备排成一列纵队,但他们不想按身高从矮到高排,那样太单调,太没个性.他们希望恰好有k对同学是高的在前,矮的在后,其余都是矮的在前,高的在后.如当n=5,k= ...

  10. Python 开发环境搭建

    Python分别有两个大的版本,分别是2和3 下载地址:Python-3.6.2   Python-2.7.13 现在安装路径:D:\Program Files\Python 安装完成以后要安装 pi ...