首页 > 编程语言 >Tarjan连通性算法模板大整合

Tarjan连通性算法模板大整合

时间:2024-10-25 20:59:02浏览次数:1  
标签:rt nxt Tarjan 连通性 int ++ dfn low 模板

更新日志

前言

由于Tarjan算法页面过多,这里统一做一个整合,后期可能还会加入或者更改这里的模板。

另外的,这个页面只提供模板——以及链接,详细讲解点链接即可。

强连通

(有向图,储存每个节点属于的分量编号)

int scnt;
int scc[N],siz[N];
int dcnt;
int dfn[N],low[N];
bool ins[N];
stack<int> stk;
void tarjan(int rt){
    low[rt]=dfn[rt]=++dcnt;
    stk.push(rt);ins[rt]=true;
    for(int i=hd[rt];i;i=ne[i]){
        if(!dfn[to[i]]){
            tarjan(to[i]);
            low[rt]=min(low[rt],low[to[i]]);
        }
        else if(ins[to[i]])low[rt]=min(low[rt],dfn[to[i]]);
    }
    if(dfn[rt]==low[rt]){
        scnt++;
        while(true){
            int tp=stk.top();stk.pop();
            ins[tp]=false;
            scc[tp]=scnt;
            siz[scnt]++;
            if(tp==rt)break;
        }
    }
}

割点

(无向图,布尔数组判断割点+vector存储割点)

int dcnt;
int dfn[N],low[N];
bool flag[N];
veci spl;
void tarjan(int rt,int fa){
    dfn[rt]=low[rt]=++dcnt;
    int ccnt=0;flag[rt]=false;
    for(int e=hd[rt];e;e=ne[e]){
        int nxt=to[e];
        if(!dfn[nxt]){
            ccnt++;
            tarjan(nxt,rt);
            low[rt]=min(low[rt],low[nxt]);
            if(!flag[rt]&&low[nxt]>=dfn[rt]&&rt!=fa){
                spl.push_back(rt);
                flag[rt]=true;
            }
        }else low[rt]=min(low[rt],dfn[nxt]);
    }
    if(!flag[rt]&&rt==fa&&ccnt>=2){
        spl.push_back(rt);
        flag[rt]=true;
    }
}

割边

(无向图,布尔数组判断桥)

int dcnt;
int dfn[N],low[N];
bool bri[M];
void tarjan(int now,int fed){
    dfn[now]=low[now]=++cnt;
    for(int e=hd[now];e;e=ne[e]){
        int nxt=to[e],eid=(e-1)/2+1;
        if(!dfn[nxt]){
            tarjan(nxt,eid);
            low[now]=min(low[now],low[nxt]);
            if(low[nxt]>dfn[now]){
                bri[eid]=true;
            }
        }else if(eid!=fed)low[now]=min(low[now],dfn[nxt]);
    }
}

点双

(无向图,vector储存连通分量所有节点编号)

int dcnt;
int dfn[N],low[N];
bool flag[N];
stack<int> stk;
int bcnt;
vector<int> bcc[N];
void tarjan(int x,int fa){
    dfn[x]=low[x]=++dcnt;
    stk.push(x);
    int ccnt=0;
    for(int e=hd[x];e;e=ne[e]){
        int nxt=to[e];
        if(!dfn[nxt]){
            ++ccnt;
            tarjan(nxt,x);
            low[x]=min(low[x],low[nxt]);
            if(low[nxt]>=dfn[x]){
                ++bcnt;
                while(1){
                    int tp=stk.top();stk.pop();
                    bcc[bcnt].push_back(tp);
                    if(tp==nxt)break;
                }
                bcc[bcnt].push_back(x);
            }
        }else low[x]=min(low[x],dfn[nxt]);
    }
    if(x==fa&&ccnt==0){
        ++bcnt;
        bcc[bcnt].push_back(x);
    }
}

边双

(无向图,vector储存连通分量所有节点编号)

int dcnt;
int dfn[N],low[N];
int scnt;
vector<int> scc[N];
stack<int> stk;
void tarjan(int x,int fed){
    dfn[x]=low[x]=++dcnt;
    stk.push(x);
    for(int e=hd[x];e;e=ne[e]){
        int nxt=to[e];
        if(!dfn[nxt]){
            tarjan(nxt,(e-1)/2+1);
            low[x]=min(low[x],low[nxt]);
        }else if(fed!=(e-1)/2+1)low[x]=min(low[x],dfn[nxt]);
    }
    if(low[x]>=dfn[x]){
        ++scnt;
        while(1){
            int tp=stk.top();stk.pop();
            scc[scnt].push_back(tp);
            if(tp==x)break;
        }
    }
}

标签:rt,nxt,Tarjan,连通性,int,++,dfn,low,模板
From: https://www.cnblogs.com/HarlemBlog/p/18503278

相关文章

  • C++之内存管理与模板初级
    内容介绍Ⅰ.C++内存管理1.C/C++内存分布2.C与C++动态内存管理方式对比2.1C中动态内存管理方式2.2C++中内存管理方式3.new和delete的底层实现原理(了解)Ⅱ.模板初阶1.模板介绍2.函数模板3.函数模板参数匹配原则4.类模板Ⅰ.C++内存管理1.C/C++内存分布intn1=1;......
  • Tarjan求点双连通分量
    更新日志思路首先,点双连通分量就是删去任意一点后仍连通的分量。如何求呢?看着定义,答案就已经在里面了——求出割点即可。与边双不同的是,点双中是包括割点的。究其原因,删去割点之后,原图会被分成多个连通块,但事实上,割点加入其中任意一个,仍然是双连通的。证明如下:若连通块......
  • 浅拷贝与深拷贝 以及嵌套和递归使用模板类
     1.浅拷贝和深拷贝——对象和类浅拷贝浅拷贝只复制对象的基本属性,而不复制引用类型的属性指向的对象,即只复制引用而不复制引用指向的对象在浅拷贝中,新对象与原始对象共享引用类型的属性指向的对象,即它们指向同一个对象。编译器提供的拷贝构造函数是浅拷贝,当一个对象修......
  • Tarjan求边双联通分量
    更新日志思路首先,我们求出原图中所有的桥,然后跑DFS给原图分区。求桥具体过程:Tarjan求桥更具体的,我们遍历每一个点,假如这个点没有被分区,那么就从这个点开始深搜。每一次深搜,都走不是桥的边,那么走到的就都属于一个边双。(很容易证明)这样,我们把每一次深搜走到的所有点分成一......
  • Tarjan求割边(桥)
    更新日志思路割边定义与割点相似,不过是把点换成了边,所以思想和割点差不多。Tarjan割点我们只需要在Tarjan过程中判断某一颗子树的low是否严格大于当前节点的dfn。值得注意,这里子树的low不应该由到它的原边回溯到它的父节点得到!究其原因,其实就是如果子树是一个强连通分量,那......
  • 一图胜千言,PPT中的数据分析模板样式
    PPT中数据可视化是一种将数据以图形或图表的形式展示出来的方法,它可以帮助观众更直观地理解数据所传达的信息。数据可视化是一个不断发展的领域,随着技术的进步,新的工具和方法不断出现,使得数据的呈现更加直观和互动。在笔格PPT,选择合适的样式模板便可直接制作图表,小编带来了各......
  • 网站修改意见文档模板?
    创建一个网站修改意见文档时,可以遵循以下模板结构,以确保信息清晰、全面且易于理解:网站修改意见文档1.文档基本信息文档标题:版本号:作者:日期:审核人:2.项目概述项目名称:项目背景:目标用户:主要功能:3.修改意见概览序号当前问题建议改进责任人预计完......
  • 如何修改网站模板的图片?后台如何修改网站内容?
    修改网站模板的图片登录后台管理系统:通常需要通过网站提供的管理员入口登录到后台管理系统。导航至模板管理:在后台找到“模板管理”或“外观设置”等相关选项。选择要编辑的模板:如果有多个模板可选,选择当前正在使用的或准备使用的模板。进入图片管理:在模板......
  • 网站模板做好了怎么修改?
    网站模板的修改通常涉及以下几个步骤:备份原始文件:在开始任何修改之前,确保备份原始的网站模板文件。这可以在出现问题时帮助你快速恢复。确定修改需求:明确你需要对网站模板进行哪些具体的修改,比如颜色调整、布局改动、功能增加等。使用合适的工具:根据模板的技术栈......
  • pbootcms修改默认首页index.html模板名称
    步骤定位到控制器文件打开 /apps/home/controller/IndexController.php 文件。查找 getIndexPage 方法在该文件中找到 privatefunctiongetIndexPage() 方法。修改模板名称在 getIndexPage 方法中,找到返回模板名称的代码块,通常如下所示:php retur......