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

相关文章

基于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

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Mysql表的简单操作(基本技能)

《Mysql表的简单操作(基本技能)》在数据库中,表的操作主要包括表的创建、查看、修改、删除等,了解如何操作这些表是数据库管理和开发的基本技能,本文给大家介绍Mysql表的简单操作,感兴趣的朋友一起看... 目录3.1 创建表 3.2 查看表结构3.3 修改表3.4 实践案例:修改表在数据库中,表的操作主要