LCA最近公共祖先模板代码
vector模拟邻接表:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#define eps 1e-8
#define memset(a,v) memset(a,v,sizeof(a))
using namespace std;
typedef long long int LL;
const int MAXL(1e4);
const int INF(0x7f7f7f7f);
const int mod(1e9+);
int dir[][]= {{-,},{,},{,},{,-}};
int father[MAXL+];
bool is_root[MAXL+];
bool vis[MAXL+];
vector<int>v[MAXL+];
int root;
int cx,cy;
int ans;
int Find(int x)
{
if(x!=father[x])
father[x]=Find(father[x]);
return father[x];
} void Join(int x,int y)
{
int fx=Find(x),fy=Find(y);
if(fx!=fy)
father[fy]=fx;
} void LCA(int u)
{
for(int i=; i<v[u].size(); i++)
{
int child=v[u][i];
if(!vis[child])
{
LCA(child);
Join(u,child);
vis[child]=true;
}
}
if(u==cx&&vis[cy]==true)
ans=Find(cy);
if(u==cy&&vis[cx]==true)
ans=Find(cx); } void init()
{
memset(is_root,true);
memset(vis,false);
int n;
scanf("%d",&n);
for(int i=; i<=n; i++)
v[i].clear();
for(int i=; i<=n; i++)
father[i]=i;
for(int i=; i<n; i++)
{
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
is_root[y]=false;
}
scanf("%d%d",&cx,&cy);
for(int i=; i<=n; i++)
{
if(is_root[i]==true)
{
root=i;
break;
}
} }
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
LCA(root);
cout<<ans<<endl;
}
}
链式前向星写法:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#define eps 1e-8
#define memset(a,v) memset(a,v,sizeof(a))
using namespace std;
typedef long long int LL;
const int MAXL(1e6);
const int INF(0x7f7f7f7f);
const int mod(1e9+);
int dir[][]= {{-,},{,},{,},{,-}};
struct node
{
int to;
int next;
}edge[MAXL+];
int head[MAXL+];
int father[MAXL+];
bool vis[MAXL+];
bool is_root[MAXL+];
int n;
int cnt;
int cx,cy;
int ans;
int root; int Find(int x)
{
if(x!=father[x])
father[x]=Find(father[x]);
return father[x];
} void Join(int x,int y)
{
int fx=Find(x),fy=Find(y);
if(fx!=fy)
father[fy]=fx;
} void add_edge(int x,int y)
{
edge[cnt].to=y;
edge[cnt].next=head[x];
head[x]=cnt++;
} void init()
{
cnt=;
memset(head,-);
memset(vis,false);
memset(is_root,true);
scanf("%d",&n);
for(int i=;i<=n;i++)
father[i]=i;
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add_edge(x,y);
is_root[y]=false;
}
for(int i=;i<=n;i++)
if(is_root[i]==true)
root=i;
} void LCA(int u)
{
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
LCA(v);
Join(u,v);
vis[v]=true; }
if(cx==u&&vis[cy]==true)
ans=Find(cy);
if(cy==u&&vis[cx]==true)
ans=Find(cx);
}
void solve()
{
scanf("%d%d",&cx,&cy);
LCA(root);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
solve();
cout<<ans<<endl;
}
}
转自:https://blog.csdn.net/baiyi_destroyer/article/details/81363221
LCA最近公共祖先模板代码的更多相关文章
- LCA(最近公共祖先)模板
Tarjan版本 /* gyt Live up to every day */ #pragma comment(linker,"/STACK:1024000000,1024000000&qu ...
- LCA最近公共祖先模板(求树上任意两个节点的最短距离 || 求两个点的路进(有且只有唯一的一条))
原理可以参考大神 LCA_Tarjan (离线) TarjanTarjan 算法求 LCA 的时间复杂度为 O(n+q) ,是一种离线算法,要用到并查集.(注:这里的复杂度其实应该不是 O(n+q) ...
- lca最短公共祖先模板(hdu2586)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 #include<iostream> #include<cstdio> ...
- Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)
Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...
- LCA(最近公共祖先)之倍增算法
概述 对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 如图,3和5的最近公共祖先是1,5和2的最近公共祖先是4 在本篇中我们先介 ...
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...
- lca 最近公共祖先
http://poj.org/problem?id=1330 #include<cstdio> #include<cstring> #include<algorithm& ...
- 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 / ...
随机推荐
- Python str byte 互相转换
- 网络请求(I)
NSURLSession 代理方法 有的时候,我们可能需要监听网络请求的过程(如下载文件需监听文件下载进度),那么就需要用到代理方法. #import "ViewController.h&q ...
- vue.js中的computed和watch的区别
1.computed在调用时不需要加(),watch是不需要调用的2.computed如果属性没有发生改变时会从缓存中读取值,watch当属性发生改变时会接收到2个值:一个为新值,一个为旧值3.com ...
- keepalived + lvs
Keepalived原理 Keepalived原理 keepalived也是模块化设计,不同模块复杂不同的功能,下面是keepalived的组件 core check vrrp libipfwc li ...
- STATS 326 Applied Time Series
STATS 326Applied Time SeriesASSIGNMENT THREEDue: 2 May 2019, 11.00 am(Worth 6% of your final grade)H ...
- freeswitch 显示主叫名称和主叫号码
1.指定主叫号码 origination_caller_id_number 参数来指定显示的主叫号码 2.指定主叫名称 origination_caller_id_name 参数来指定显示的主叫名称 ...
- [js] - 前端FileReader使用,适用于文件上传预览.(并未传入后端)
<body> <div class="box"> <div class="container"> <ul> &l ...
- (转载)Unity 关于动态监听时,点击Button,返回其在数组中的下标
其实是绕了一圈,把数组里的元素放进数组列表里再读取它的下标 using System.Collections; using System.Collections.Generic; using Unit ...
- Learning-Python【25】:绑定方法与非绑定方法
类中定义函数分为了两大类,绑定方法与非绑定方法,它们有一些特殊之处: 1.绑定方法特殊之处:绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数自动传入 绑定给对象的方法:这个在面向对象第一篇第六 ...
- HDU2476 String painter——区间DP
题意:要把a串变成b串,每操作一次,可以使a串的[l,r]区间变为相同的一个字符.问把a变成b最少操作几次. 这题写法明显是区间dp ,关键是处理的方法. dp[l][r]表示b串的l~r区段至少需要 ...