Tarjan 算法求 LCA / Tarjan 算法求强连通分量
- 【时光蒸汽喵带你做专题】最近公共祖先 LCA (Lowest Common Ancestors)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili
- tarjan LCA - YouTube
- Tarjan算法_LCA - A_Bo的博客 - CSDN博客
- Tarjan离线算法求最近公共祖先(LCA) - 初学者 - CSDN博客
- 最近公共祖先(LCA) - riteme.site
- Fuzhou University OnlineJudge 1628
- P3379 【模板】最近公共祖先(LCA) - 洛谷 | 计算机科学教育新生态
- 有向图强连通分量的Tarjan算法 - BYVoid
- Tarjan算法 详解+心得 - Christopher_Yan - 博客园
- UESTCACM 每周算法讲堂第25期 Tarjan求强连通分量_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili
洛谷P3379 【模板】最近公共祖先(LCA)
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include <set>
#include <stack>
#include <map>
#include<vector>
using namespace std;
const int maxn = 5e5 + 5;
struct query
{
int x;
int y;
int lca;
}query[maxn];
int fa[maxn];
bool vis[maxn];
int deep[maxn];
vector<int> G[maxn];
vector<int> Q[maxn];
void init()
{
for (int i = 0; i < maxn; i++)
{
fa[i] = i;
}
}
int find(int x)
{
if (fa[x] == x)
return x;
else
return fa[x] = find(fa[x]);
}
void Union(int v, int u)
{
int vfa = find(v), ufa = find(u);
if (vfa == ufa)return;
else fa[v] = u;
}
void tarjan(int u)
{
vis[u] = true;
for (auto qid : Q[u]) {
if (query[qid].x == u) {
if (vis[query[qid].y]) {
query[qid].lca = find(query[qid].y);
}
}
else
{
if (vis[query[qid].x]) {
query[qid].lca = find(query[qid].x);
}
}
}
for (auto v : G[u]) {
if (vis[v])
continue;
deep[v] = deep[u] + 1;
tarjan(v);
Union(v, u);
}
}
int main()
{
init();
int n, m, s;
scanf_s("%d%d%d", &n, &m, &s);
int x, y;
for (int i = 1; i < n; i++)
{
scanf_s("%d%d", &x, &y);
G[x].push_back(y);
G[y].push_back(x);
}
for (int i = 1; i <= m; i++)
{
scanf_s("%d%d", &query[i].x, &query[i].y);
Q[query[i].x].push_back(i); // 对于节点 x 来说有一个编号为 i 的询问
Q[query[i].y].push_back(i);
}
tarjan(s);
for (int i = 1; i <= m; i++)
{
printf("%d\n", query[i].lca);
}
for (int i = 1; i <= n; i++)
{
printf("节点 %d 的深度是 %d\n", i, deep[i]);
}
}
FOJ 1628 计算公共祖先的个数
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include <set>
#include <stack>
#include <map>
#include<vector>
using namespace std;
const int maxn = 5e5 + 5;
struct query
{
int x;
int y;
int lca;
}query[maxn];
int fa[maxn];
bool vis[maxn];
int deep[maxn];
vector<int> G[maxn];
vector<int> Q[maxn];
void init()
{
deep[1] = 1;
for (int i = 0; i < maxn; i++)
{
fa[i] = i;
}
}
int find(int x)
{
if (fa[x] == x)
return x;
else
return fa[x] = find(fa[x]);
}
void Union(int v, int u)
{
int vfa = find(v), ufa = find(u);
if (vfa == ufa)return;
else fa[v] = u;
}
void tarjan(int u)
{
for (int i = 0; i < Q[u].size(); i++) {
if (query[Q[u][i]].x == u) {
if (vis[query[Q[u][i]].y]) {
query[Q[u][i]].lca = find(query[Q[u][i]].y);
}
}
else
{
if (vis[query[Q[u][i]].x]) {
query[Q[u][i]].lca = find(query[Q[u][i]].x);
}
}
}
vis[u] = true;
for (int i = 0; i < G[u].size(); i++) {
if (vis[G[u][i]])
continue;
deep[G[u][i]] = deep[u] + 1;
tarjan(G[u][i]);
Union(G[u][i], u);
}
}
int main()
{
init();
int n, k, m;
int x, y;
scanf_s("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf_s("%d", &k);
for (int j = 1; j <= k; j++)
{
scanf_s("%d", &y);
G[i].push_back(y);
G[y].push_back(i);
}
}
scanf_s("%d", &m);
for (int i = 1; i <= m; i++) // 离线处理
{
scanf_s("%d%d", &query[i].x, &query[i].y);
Q[query[i].x].push_back(i); // 对于节点 x 来说有一个编号为 i 的询问
Q[query[i].y].push_back(i);
}
tarjan(1);
/*for (int i = 1; i <= m; i++)
{
printf("%d\n", query[i].lca);
}
for (int i = 1; i <= n; i++)
{
printf("节点 %d 的深度是 %d\n", i, deep[i]);
}*/
for (int i = 1; i <= m; i++)
{
printf("%d\n", deep[query[i].lca]);
}
}
Tarjan 算法求 LCA / Tarjan 算法求强连通分量的更多相关文章
- Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】
一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...
- (转)Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)
基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...
- SPOJ 10628 Count on a tree(Tarjan离线 | RMQ-ST在线求LCA+主席树求树上第K小)
COT - Count on a tree #tree You are given a tree with N nodes.The tree nodes are numbered from 1 to ...
- 算法数据结构 | 三个步骤完成强连通分量分解的Kosaraju算法
强连通分量分解的Kosaraju算法 今天是算法数据结构专题的第35篇文章,我们来聊聊图论当中的强连通分量分解的Tarjan算法. Kosaraju算法一看这个名字很奇怪就可以猜到它也是一个根据人名起 ...
- HDU-2874-森林求LCA/tarjan
http://acm.hdu.edu.cn/showproblem.php?pid=2874 给出一个森林,询问任意两点最短距离. tarjan跑一遍即可,就是这个题卡内存,vector会MLE,换前 ...
- 算法笔记--lca倍增算法
算法笔记 模板: vector<int>g[N]; vector<int>edge[N]; ][N]; int deep[N]; int h[N]; void dfs(int ...
- Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量
在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的 ...
- 求LCA最近公共祖先的离线Tarjan算法_C++
这个Tarjan算法是求LCA的算法,不是那个强连通图的 它是 离线 算法,时间复杂度是 O(m+n),m 是询问数,n 是节点数 它的优点是比在线算法好写很多 不过有些题目是强制在线的,此类离线算法 ...
- 最近公共祖先LCA(Tarjan算法)的思考和算法实现
LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...
随机推荐
- 【leetcode-148】排序链表
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序. 示例 1: 输入: 4->2->1->3输出: 1->2->3->4示例 2: 输入: ...
- C# 用Singleton类构建多线程单例模式
public sealed class Singleton { private static volatile Singleton uniqueInstance; p ...
- mvc视图双下拉框联动
html部分的代码 <tr class="trs"> <td class="item1"><div class="ite ...
- 模板模式创建一个poi导出功能
之前的导出都很乱,直接写在代码中,等到下回还使用导出功能时又不知如何下手,今天用模板模式重写了一个导出功能,方便以后使用: package com.sf.addrCheck.util.export.p ...
- 记一次CSS反爬
目标网址:猫眼电影 主要流程 爬取每一个电影所对应的url 爬取具体电影所对应的源码 解析源码,并下载所对应的字体 使用 fontTools 绘制所对应的数字 运用机器学习的方法识别对应的数字 在源码 ...
- Java中assert(断言)的使用
Java中assert(断言)的使用 1.Eclipse中默认assert(断言)是关闭,开启方式如下: 简单来说:就是设置一下jvm的参数,参数是-enableassertions或者-ea(推荐) ...
- CTF-代码审计(2)
1.bugku 备份是个好习惯 网址:http://123.206.87.240:8002/web16/ 进去什么都没有,题目说备份想到备份文件,所以直接再后面加个 .bak 拿到源码: < ...
- gdb gdbtui
1. gdbtui 打开tui模式 gdbtui a.out gdb -tui a.out 调试一个正在运行的进程 gdb -p pid 在linux自带的终端里是正常显示的,但是在securecrt ...
- druid获取不需要配置公钥私钥的密文,或者明文
import com.alibaba.druid.filter.config.ConfigTools; /** * Created with IntelliJ IDEA on 2019/3/21. * ...
- Nginx Rewrite相关功能-防盗链
Nginx Rewrite相关功能-防盗链 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.