首页 > 编程语言 >LCA 离线tarjan算法

LCA 离线tarjan算法

时间:2023-07-18 19:34:59浏览次数:36  
标签:tarjan 子树 int 离线 fa MAXN LCA include


tarjan算法是离线算法,它必须先将所有的要查询的点对存起来,然后在搜的时候输出结果。

tarjan算法很经典,因为算法的思想很巧妙,利用了并查集思想,在dfs下,将查询一步一步的搜出来。

伪代码如下:

LCA 离线tarjan算法_i++

可以看到,对于我们已经保存好的查询,假设为(u,v),u为此时已经搜完的子树的根节点,v的位置就只有两种可能,一种是在u的子树内,另一种就是在其之外。

对于在u的子树内的话,最近公共祖先肯定是可以直接得出为u;

对于在u的子树之外的v,我们已经将v搜过了,且已经知道了v的祖先,那么我们可以根据dfs的思想,v肯定是和u在一颗子树下的,而且这颗子树是使得他们能在一颗子树下面深度最深的。而这个子树的根节点刚好就是v的并查集所保存的祖先。所以对于这种情况的(u,v),它们的最近公共祖先就是v的并查集祖先。


poj 1470 


#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
using namespace std;

#define  MAXN 1001

int fa[MAXN];
int ques[MAXN][MAXN];
int ind[MAXN];
bool vis[MAXN];
int cnt[MAXN];
vector<int>edge[MAXN];
int n,m;

int find_father(int k) {
    if(fa[k] == k)return k;
    else return fa[k] = find_father(fa[k]);
}

void tarjan(int x){
    for (int i=1; i<=n; i++) {
        if (vis[i] && ques[x][i])
            cnt[find_father(i)] += ques[x][i];
    }
    fa[x] = x;
    vis[x] = true;
    for (int i=0; i<edge[x].size(); i++) {
        tarjan(edge[x][i]);
        fa[edge[x][i]] = x;
    }


}


int main() {
    while (~scanf("%d", &n)) {
        for (int i=1; i<=n; i++) {
            edge[i].clear();
        }
        memset(ques, 0, sizeof(ques));
        memset(vis, false, sizeof(vis));
        memset(cnt, 0, sizeof(cnt));
        memset(ind, 0, sizeof(ind));

        int a, b;
        for (int i=0; i<n; i++) {
            scanf("%d:(%d)", &a, &m);
            for (int j=0; j<m; j++) {
                scanf(" %d", &b);
                edge[a].push_back(b);
                ind[b]++;
            }
        }
        scanf("%d", &m);
        for (int i=0; i<m; i++) {
            scanf(" (%d %d)", &a, &b);
            ques[a][b]++;
            ques[b][a]++;
        }

        for (int i=1; i<=n; i++)
            if (!ind[i]) {
                tarjan(i); break;
            }
        for (int i=1; i<=n; i++)
            if (cnt[i]) printf("%d:%d\n", i, cnt[i]);
    }
    return 0;
}




标签:tarjan,子树,int,离线,fa,MAXN,LCA,include
From: https://blog.51cto.com/u_16192154/6767463

相关文章

  • .Net Framework 离线安装包
    .NETFramework2.0ServicePack1x86:https://download.microsoft.com/download/0/8/c/08c19fa4-4c4f-4ffb-9d6c-150906578c9e/NetFx20SP1_x86.exex64:https://download.microsoft.com/download/9/8/6/98610406-c2b7-45a4-bdc3-9db1b1c5f7e2/NetFx20SP1_x64.exe.NETFram......
  • ubuntu 22.04离线安装cuda 11.7.1、cudnn 8.9.3.28、nccl 2.18.3、tensorrt 8.6.1
    最近在使用飞桨OCR,有几个特殊的符号需要进行识别,手上只有两台机器,一台1080TI单卡(windows11),一台1080Ti双卡(linux22.04),习惯性追新到飞桨最高支持的cuda11.7,其实1080Ti到cuda10就够用了,后面的新版本差没有明显的性能提升。windows上无脑安装,linux上安装比较麻烦,记录下安装过程......
  • Java-Day-32( 多用户即时通信系统 —— 文件传输 + 服务器推送新闻 + 离线留言 )
    Java-Day-32多用户即时通信系统文件传输思路:客户端里先把文件读取到客户端为字节数组,把文件对应的字节数组封装到message对象,内含文件内容、sender、getter,将message对象发送给服务端拆解message对象获取getterid,获取客户端被指定的接收用户的通信线程,把message转......
  • tarjan 学习笔记
    tarjan学习笔记求解强联通分量我们从一个点开始建立dfs树,有如下四种边:树边若\(u\)到\(v\)有边,且满足\(v\)没有被访问过,则这条边为树边返祖边若\(u\)到\(v\)有边,且满足\(v\)已被访问过,则这条边为返祖边横叉边若\(u\)到\(v\)有边,且满足\(u\)和......
  • 快速离线安装MySql数据库
    一、mysal压缩文件通过ftp放入\opt-->解压cd/opttar-xzvfmysql-5.7.29-linux-glibc2.12-×86_64.tar.gz二、移动一>创建data目录一>创建用户组mvmysql-5.7.29-linux-glibc2.12-×86_64/usr/localcd/usr/localmvmysql-5.7.29-linux-glibc2.12-×86_64mysqlcd......
  • 用户案例 | Apache DolphinScheduler 离线调度在自如多业务场景下的应用与实践
    用户案例|自如随着自如业务的快速发展,不断增长的调度任务和历史逾万的存量任务对平台稳定性提出了更高的要求。同时,众多非专业开发人员也需要一种更为“亲民”的调度平台使用体验。如何满足这些日渐凸显的需求对自如大数据平台的开发团队来说,无疑是巨大的挑战。团队经过深入......
  • 【雕爷学编程】Arduino动手做(160)---HLK-V20离线语音模块2
    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手试试多做实验,不管成功与否,都会记录下来——小小的进步或是搞不掂的问题......
  • 【雕爷学编程】Arduino动手做(160)---海凌科HLK-V20离线语音模块
    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手试试多做实验,不管成功与否,都会记录下来——小小的进步或是搞不掂的问题......
  • 【学习笔记】Tarjan
    前言:凡事都得靠自己--bobo催隔壁K8Hen天了让他写Tarjan的学习笔记,但貌似还没有动静,所以决定自己写一个。正文本文配套题单:14.图论-tarjan(强连通分量、割点、割边)前置知识熟练使用链式前向星强连通、强连通图、强连通分量的定义(详见oi-wiki,这里不再赘述)如图......
  • Redhat离线安装gitlab,迁移数据,指定数据存放位置
    一、安装gitlab1、安装依赖包yuminstall-ycurlpolicycoreutils-pythonopenssh-serveropenssh-clients#开启sshd服务systemctlenablesshdsystemctlstartsshd 2、下载rpm包并安装如需迁移备份数据,新机器安装gitlab版本需跟旧机器gitlab版本保持一致查看旧机器g......