Johnson算法寻找图中的所有简单环路

2024-01-27 01:08

本文主要是介绍Johnson算法寻找图中的所有简单环路,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Johnson算法论文:https://www.cs.tufts.edu/comp/150GA/homeworks/hw1/Johnson%2075.PDF

Johnson算法讲解视频:https://www.youtube.com/watch?v=johyrWospv0

一篇解释原理较好的博客:https://blog.csdn.net/Azeroit/article/details/105401120?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase

C++实现代码:

#include <iostream>
#include<vector>
#include<map>
#include<cstring>
using namespace std;//using johnson algorithm
int visited[10010],dfn[10010],low[10010],ins[10010],stack[10010],color[10010],top=0,cnt,N,M,stamp=0;
vector<int> V[10010],VC[10010];
vector<int> scc[10010];map<int,vector<int>> blockedmap;  //stack,ins 可以重复利用,ins充当blockedset的作用 先用vector,不对就换set
vector<vector<int>> ans;  //存放结果
void tarjan(int u){dfn[u]=low[u]=++stamp;stack[++top]=u;ins[u]=1;for(int i=0;i<V[u].size();i++){int v=V[u][i];if(!dfn[v]){tarjan(v);low[u]=min(low[u],low[v]);}else if(ins[v])low[u]=min(low[u],dfn[v]);}if(dfn[u]==low[u]){cnt++; int y;do {y = stack[top--], ins[y] = 0;/*c[y] = cnt, */color[y] = cnt,scc[cnt].push_back(y);} while (u!= y);}
}void stronglycomponent(){for(int i=1;i<=N;i++){if(!dfn[i]) tarjan(i);}
}void unlock(int u){ins[u]=0;if(!blockedmap[u].empty()){for(auto e:blockedmap[u]){if(ins[e]) unlock(e);}}blockedmap[u].clear();
}
bool Findcycles(int start,int cur){//printf("f(%d,%d)\n",start,cur);bool f=false;// 是否找到环stack[++top]=cur;ins[cur]=1;for(auto e:VC[cur]){if(!visited[e]){if(e==start){//保存结果vector<int> path;for(int i=1;i<=top;i++)path.push_back(stack[i]);ans.push_back(path);f=true;}else if(!ins[e]){//bool flag=Findcycles(start,e);  //不能合并写f=(Findcycles(start,e))||f;  //次序不能颠倒}}}if(f) unlock(cur);else{for(auto e:VC[cur]){if(!visited[e]) blockedmap[e].push_back(cur);}}--top;return f;
}
int main()
{cin>>N>>M;//默认编号0-N-1for(int i=0;i<M;i++){int a,b;cin>>a>>b;V[a].push_back(b);}stronglycomponent();//显示强连通分量printf("显示强连通分量\n");cout<<"cnt is "<<cnt<<endl;for(int i=1;i<=cnt;i++){for(int j=0;j<scc[i].size();j++){printf("%d ",scc[i][j]);}printf("\n");}//缩点for(int i=1;i<=N;i++){for(int j=0;j<V[i].size();j++){if(color[i]==color[V[i][j]]){VC[i].push_back(V[i][j]);}}}//寻找所有简单回路memset(ins,0,sizeof(ins));for(int startindex=1;startindex<=N;startindex++){Findcycles(startindex,startindex);visited[startindex]=1;}//显示结果printf("显示结果\n");for(int i=0;i<ans.size();i++){for(int j=0;j<ans[i].size();j++){printf("%d ",ans[i][j]);}printf("\n");}
}

以视频中的输入例子为测试:

输入:

9 15
1 2
1 5
1 8
2 3
2 7
2 9
3 1
3 2
3 4
3 6
4 5
5 2
6 4
8 9
9 8

输出:

1 2 3
1 5 2 3
2 3
2 3 4 5
2 3 6 4 5
8 9

 

这篇关于Johnson算法寻找图中的所有简单环路的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/648613

相关文章

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

Python打印对象所有属性和值的方法小结

《Python打印对象所有属性和值的方法小结》在Python开发过程中,调试代码时经常需要查看对象的当前状态,也就是对象的所有属性和对应的值,然而,Python并没有像PHP的print_r那样直接提... 目录python中打印对象所有属性和值的方法实现步骤1. 使用vars()和pprint()2. 使

Python pip下载包及所有依赖到指定文件夹的步骤说明

《Pythonpip下载包及所有依赖到指定文件夹的步骤说明》为了方便开发和部署,我们常常需要将Python项目所依赖的第三方包导出到本地文件夹中,:本文主要介绍Pythonpip下载包及所有依... 目录步骤说明命令格式示例参数说明离线安装方法注意事项总结要使用pip下载包及其所有依赖到指定文件夹,请按照以

基于Python实现一个简单的题库与在线考试系统

《基于Python实现一个简单的题库与在线考试系统》在当今信息化教育时代,在线学习与考试系统已成为教育技术领域的重要组成部分,本文就来介绍一下如何使用Python和PyQt5框架开发一个名为白泽题库系... 目录概述功能特点界面展示系统架构设计类结构图Excel题库填写格式模板题库题目填写格式表核心数据结构

C/C++ chrono简单使用场景示例详解

《C/C++chrono简单使用场景示例详解》:本文主要介绍C/C++chrono简单使用场景示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录chrono使用场景举例1 输出格式化字符串chrono使用场景China编程举例1 输出格式化字符串示

windows和Linux安装Jmeter与简单使用方式

《windows和Linux安装Jmeter与简单使用方式》:本文主要介绍windows和Linux安装Jmeter与简单使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows和linux安装Jmeter与简单使用一、下载安装包二、JDK安装1.windows设

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Springboot实现推荐系统的协同过滤算法

《Springboot实现推荐系统的协同过滤算法》协同过滤算法是一种在推荐系统中广泛使用的算法,用于预测用户对物品(如商品、电影、音乐等)的偏好,从而实现个性化推荐,下面给大家介绍Springboot... 目录前言基本原理 算法分类 计算方法应用场景 代码实现 前言协同过滤算法(Collaborativ

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

MySQL中动态生成SQL语句去掉所有字段的空格的操作方法

《MySQL中动态生成SQL语句去掉所有字段的空格的操作方法》在数据库管理过程中,我们常常会遇到需要对表中字段进行清洗和整理的情况,本文将详细介绍如何在MySQL中动态生成SQL语句来去掉所有字段的空... 目录在mysql中动态生成SQL语句去掉所有字段的空格准备工作原理分析动态生成SQL语句在MySQL