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算法寻找图中的所有简单环路相关推荐

  1. 算法-寻找数组中的重复值,四种解法

    算法-寻找数组中的重复值 寻找数组中的重复值 寻找数组中的重复值 题目来源于:Leetcode-287.本题归类到简单我无法理解-要满足四个条件需要用很特定的解法,面试中要是用到的话很可能是在给自己挖 ...

  2. 【图论刷题-5】力扣 1971. 寻找图中是否存在路径

    图论刷题 机器人的运动范围 矩阵中的路径 图像渲染 水位上升的泳池中游泳 寻找图中是否存在路径 1971. 寻找图中是否存在路径 力扣原题 地址 难度与标签 简单难度 深度优先遍历 广度优先遍历 并查 ...

  3. LeetCode 1971. 寻找图中是否存在路径

    [LetMeFly]1971.寻找图中是否存在路径 力扣题目链接:https://leetcode.cn/problems/find-if-path-exists-in-graph/ 有一个具有 n个 ...

  4. Dijkstra算法求解图中最短路径距离

    前言:这里是自学内容,讲解的是用python来实现Dijkstra算法,算是入门求解图中最短路径问题的典型案例. 算法简介: 迪杰斯特拉(Dijkstra)算法是一个按照路径长度递增的次序产生的最短路 ...

  5. 寻找图中所有哈密尔顿环(不重复)

    哈密尔顿环是指不重复地走过所有的点,并且最后还能回到起点的回路.使用简单的深度优先搜索,就能求出一张图中所有的哈密尔顿环,下面给出一段参考程序: 现在给出一张图如下: 输入:              ...

  6. opencv 寻找图中的corners 利用自带 Shi-Tomasi Corner Detector 实现

    import numpy as np import cv2 as cv from matplotlib import pyplot as pltimg = cv.imread('duomianti.j ...

  7. 图的最短路径算法及matlab实现(Dijkstra算法、Floyd算法、Bellman-Ford算法、Johnson 算法)

    图的最短路径算法 Dijkstra算法 Dijkstra算法研究的是从初始点到其他任一结点的最短路径,即单源最短路径问题,其对图的要求是不存在负权值的边. Dijkstra算法主要特点是以起始点为中心 ...

  8. 数据结构与算法——31. 图的应用:拓扑排序、强连通分支、最短路径问题、最小生成树

    文章目录 一.拓扑排序(Topological Sort) 实现思路 二.强连通分支 1. 转置的概念 2. 强连通分支算法:Kosaraju算法思路 三.最短路径问题 1. 最短路径问题:Dijks ...

  9. 获得有向无环图中起点到终点的所有路径_力扣1514——概率最大的路径

    本题主要和图的遍历求解最短路径相关,可以用 Dijkstra 或者 Bellman-Ford 算法进行解决. 原题 给你一个由 n 个节点(下标从 0 开始)组成的无向加权图,该图由一个描述边的列表组 ...

  10. 回溯算法在点菜中的应用例子

    本人其实内心很抵触去埋头刷算法题,但是有一些算法在实际业务开发中或者思想上还是值得借鉴的,因此通过这种结合实际场景的小Demo来学习和理解算法也可能是对算法提起兴趣对抗枯燥的一种方法吧. 在看< ...

最新文章

  1. [转载]TFS测试管理
  2. USB有时adb shell连不上设备
  3. MyBatis-20MyBatis高级结果映射【一对一映射(4种方式)】
  4. 进制转换(sdut1252)_JAVA
  5. 第十三届“华中杯”大学生数学建模挑战赛题目 B 题 技术问答社区重复问题识别
  6. java创建指定日期_如何创建指定的日期和时间
  7. OpenFileDialog 打开文件对话框
  8. python中使用什么导入模块-python—模块导入和类
  9. JVM性能分析与定位
  10. 附26页PPT下载|借助用户画像解决电商问题
  11. C语言课设图书管理系统(大作业)
  12. 两阶段网络DEA及其计算
  13. uva 10099 The Tourist Guide nyoj 1019 亲戚来了【单个路线最大流【最短路算法】】
  14. maven依赖名词解释
  15. 面试系列(九):商汤科技 深度学习平台C++研发
  16. kubernetes日志架构PLG(promtail+loki+grafana)
  17. matlab能否算高中数学题,Matlab软件在高中数学学习中的应用
  18. outlook gmail setting
  19. Android读取中文文件乱码解决方法
  20. ICML 2022 | 基于有偏不对称对比学习的长尾分布外检测

热门文章

  1. 微信下载录音文件(音轨分离 ffmpeg视频合成)
  2. 数值计算原理_数值方法中的有限元法、有限差分法、有限体积法的区别
  3. Java字符串排序后输出
  4. 软考《软件设计师教程》(第五版)
  5. 网络攻防技术——端口扫描
  6. WinRAR安装程序打包教程
  7. 大智慧公式系统:条件选股之基本技巧
  8. 【Codecs系列】HEVC标准(九):环路滤波技术之SAO
  9. 黑客帝国,社会化网络
  10. Socket编程入门(一)实现简单的Socket实例