洛谷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 算法求强连通分量的更多相关文章

  1. Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】

    一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...

  2. (转)Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)

    基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...

  3. 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  ...

  4. 算法数据结构 | 三个步骤完成强连通分量分解的Kosaraju算法

    强连通分量分解的Kosaraju算法 今天是算法数据结构专题的第35篇文章,我们来聊聊图论当中的强连通分量分解的Tarjan算法. Kosaraju算法一看这个名字很奇怪就可以猜到它也是一个根据人名起 ...

  5. HDU-2874-森林求LCA/tarjan

    http://acm.hdu.edu.cn/showproblem.php?pid=2874 给出一个森林,询问任意两点最短距离. tarjan跑一遍即可,就是这个题卡内存,vector会MLE,换前 ...

  6. 算法笔记--lca倍增算法

    算法笔记 模板: vector<int>g[N]; vector<int>edge[N]; ][N]; int deep[N]; int h[N]; void dfs(int ...

  7. Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量

    在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的 ...

  8. 求LCA最近公共祖先的离线Tarjan算法_C++

    这个Tarjan算法是求LCA的算法,不是那个强连通图的 它是 离线 算法,时间复杂度是 O(m+n),m 是询问数,n 是节点数 它的优点是比在线算法好写很多 不过有些题目是强制在线的,此类离线算法 ...

  9. 最近公共祖先LCA(Tarjan算法)的思考和算法实现

    LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...

随机推荐

  1. 浅谈Nginx以及特性

    Nginx以及特性 1.Nginx是什么? Nginx是一个高性能的HTTP和反向代理轻量级web服务器,特点:占用内存少,处理并发能力强.Nginx专为性能优化而开发,性能是其最重要的考量 ,能经受 ...

  2. 给easyui datebox扩展一个清空按钮,无侵入

    /** * 给时间框控件扩展一个清除的按钮 */ $.fn.datebox.defaults.cleanText = '清空'; (function ($) { var buttons = $.ext ...

  3. scrapy设置logger日志

    1.在settings中设置log级别,在settings.py中添加一行: LOG_LEVEL = 'WARNING' Scrapy提供5层logging级别: CRITICAL - 严重错误 ER ...

  4. 部署LNMP应用平台

    一.LNMP应用平台概述 1.概述:LNMP代表的就是:Linux系统下Nginx+MySQL+PHP这种网站服务器架构.Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/ ...

  5. Nginx应用详解及配置

    一.Nginx简介 概述:Nginx是一款由俄罗斯开发的开源的高性能HTTP服务器和反向代理服务器,同时支持IMAP/POP3/SMTP代理服务,其性能优势着为显著,官网上称:单台nginx服务器可以 ...

  6. How to: Create a C/C++ Union by Using Attributes (C#)

    [How to: Create a C/C++ Union by Using Attributes (C#)] 1.you can create what is known as a union in ...

  7. vue - 过滤器-钩子函数路由

    一.关于路由 1.使用vue router 本质上是声明一种可以通过路径进行 挂子,用子 找到对应的 template 进行页面渲染 <!DOCTYPE html> <html la ...

  8. CEfSharp下载文件 弹出保存框,实现 IDownloadHandler 接口

    上节讲了如何将CefSharp集成到C#中,但集成后将web界面链接进ChromiumWebBrowser后,但web界面上下载附件的功能不好使咯. 百度了半天还是没搞定,只能去看官网的Excampl ...

  9. Discuz!开发之时间处理函数dgmdate()详解

    使用过Discuz!的朋友都会知道Discuz!的时间可以显示成多少秒前.多少分钟前.几个小时前.几天前等等,而不是单纯的显示标准时间,这样的时间显示方式就更显得人性化了!   那么Discuz!是如 ...

  10. element-ui级联选择器(Cascader)获取级联对象 (主要是想获取:label值)

    最近使用element-ui 的Casecader 级联对象时,后台要求将对象的label值也传过去,然而,element-ui 官方并没有提供这样方(keng)便 ( die ) 的方法. 一时间直 ...