一、定义:

强连通图(Strongly Connected Graph)是指在有向图G中,如果对于每一对vi、vj,vi≠vj,从vi到vj和从vj到vi都存在路径,则称G是强连通图。

二、判断是不是强连通图的算法:

下面是Kosaraju基于DFS的简单算法,这算法对图进行了两次DFS遍历:

1) 将所有顶点初始化为未访问。

2)从任意顶点v开始进行图的DFS遍历。如果DFS遍历没有访问完所有顶点,则返回false

3)反转所有圆弧

4)将所有顶点标记为未在反向图中访问。

5)从相同的顶点v开始进行反向图的DFS遍历(与步骤2相同)。如果DFS遍历不访问所有顶点,则返回false。否则返回true

原理:


翻译下?
就是说:
对于无向图,如果从任意一个顶点v开始DFS或者BFS可以到达所有其他顶点,那么其他的顶点至少可以通过一条包含v的路径来到达除自己外的顶点。
对于有向图来说,如果从任意一个顶点v开始DFS或者BFS可以到达所有其他顶点,然后把有向图的边反向,在从顶点v开始DFS或者BFS可以再次到达所有其他顶点,
那么就意味着在原图中所有其他顶点都可以到达顶点v而如果v可以到达所有其他顶点,所有其他顶点又可以到达v,那么其他的顶点至少可以通过一条包含v的路径来到达除自己外的顶点。根据定义,这样图肯定就是强连通图了。

黄色字体解释:
“如果顶点u可以到达v,那么如果反转u和v之间的路径的边缘,则现在v可以等效地到达u,并且如果在原始点中没有从u到v的路径,则在转置v和u’之间没有路径"

来自:https://cs.stackexchange.com/questions/19652/kosaraju-s-algorithm-why-transpose

代码实现:

DFSBFS都写了,用的是BFS,要用DFS的话把isSC里的两个BFSUtil改成DFSUtil就可以

#include<iostream>
#include<list>
#include<queue>
using namespace std;class Graph
{int n;list<int>*adj;     //邻接表 void DFSUtil(int u, bool visited[]); void BFSUtil(int u, bool visited[]);
public:Graph(int _n){ n = _n;  adj = new list<int>[_n]; }~Graph(){  delete [] adj; }void addEdge(int v,int w);Graph getTranspose(); bool isSC();        //返回是不是强连同图
};
void Graph::addEdge(int v, int w)
{adj[v].push_back(w);
}
Graph Graph::getTranspose()     //有向图反向
{Graph g(n);for(int i = 0; i < n; i++){list<int>::iterator it;for(it = adj[i].begin(); it != adj[i].end(); it++){g.addEdge(*it, i);     //反向添加 } }return g;
}
void Graph::DFSUtil(int u,bool visited[])  //DFS
{visited[u] = true;list<int>::iterator it;for(it = adj[u].begin(); it != adj[u].end(); it++){if(!visited[*it]){DFSUtil(*it,visited); }}
}
bool Graph::isSC()
{bool *visited = new bool[n];for(int i = 0; i < n; i++){visited[i] = false;}BFSUtil(0,visited);                 //从0开始DFS for(int i = 0; i < n; i++){if(visited[i] == false)        //不连通 {return false;}}Graph  gr = getTranspose();      //得到反向的有向图 for(int i = 0; i < n; i++){visited[i] = false;}gr.BFSUtil(0,visited);               //从0开始对反向的有向进行DFS for(int i = 0; i < n; i++){if(visited[i] == false)      //不连通 {return false;}}return true;
}
void Graph::BFSUtil(int u,bool visited[])       //BFS
{queue<int> q;q.push(u);visited[u] = true;list<int>::iterator it;while(!q.empty()){int v = q.front();q.pop();for(it = adj[v].begin(); it != adj[v].end(); it++){if(!visited[*it]){q.push(*it);visited[*it] = true;} }}
}
int main()
{ Graph g1(5); g1.addEdge(0, 1); g1.addEdge(1, 2); g1.addEdge(2, 3); g1.addEdge(3, 0); g1.addEdge(2, 4); g1.addEdge(4, 2); g1.isSC()? cout << "Yes\n" : cout << "No\n"; Graph g2(4); g2.addEdge(0, 1); g2.addEdge(1, 2); g2.addEdge(2, 3); g2.isSC()? cout << "Yes\n" : cout << "No\n"; return 0;
}

强连通图------(1)通过两次DFS或BFS判断是不是强连通图相关推荐

  1. 【深度优先搜索】一个实例+两张动图彻底理解 DFS | DFS 与 BFS 的区别 | 用 DFS 自动控制我们的小游戏

    前言: 在第一篇文章中(link),我们讨论了 如何用 pygame 写一个小游戏,并用键盘交互控制 .接下来,我们将分别用 DFS .BFS .DRL 实现自动控制.这篇文章讨论了什么是深度优先搜索 ...

  2. dfs、bfs时候染色算法和直接传一个visited两种方法

    以695. 岛屿的最大面积为例: 在图的遍历中,如果不加任何约束,DFS和BFS一定会遍历到重复节点,解决这个问题的一个方法就是在函数外定义一个visited=set(),然后每次遍历的时候把未在vi ...

  3. 【数据结构笔记21】图的遍历,DFS与BFS,连通图

    本次笔记内容: 6.2.1 图的遍历 - DFS 6.2.2 图的遍历 - BFS 6.2.3 图的遍历 - 为什么需要两种遍历 6.2.4 图的遍历 - 图连不通怎么办? 文章目录 深度优先搜索(D ...

  4. LeetCode算法题7:DFS和BFS

    文章目录 前言 深度优先搜索算法伪代码: 广度优先搜索算法伪代码: 一.图像渲染 DFS: BFS: 上面BFS算法存在的问题: 修改 1: 修改 2: 二.岛屿的最大面积 DFS: BFS : 三. ...

  5. 连通图的判断(并查集, DFS, BFS)

    首先要明确什么是连通图??? 连通图:对于一个图来说,图中的任意一个点都能访问到所有的点,则说明该图连通 很明显,如果要判断一个图是否连通,则必须要从任意一个搜索一遍,判断是否到达了所有的点,则很快会 ...

  6. PAT甲级1099 Build A Binary Search Tree (30分):[C++题解]建立二叉搜索树、dfs和bfs

    文章目录 题目分析 题目链接 题目分析 题意重述:给定一棵二叉树的结构,和待填的数值,请将数据填到二叉树中的结点中,使之满足二叉搜索树的性质. 然后按照层序遍历输出数值. 分析: 本题分两步. 第一步 ...

  7. 一文搞懂深度优先搜索、广度优先搜索(dfs、bfs)

    前言 你问一个人听过哪些算法,那么深度优先搜索(dfs)和宽度优先搜索(bfs)那肯定在其中,很多小老弟学会dfs和bfs就觉得好像懂算法了,无所不能,确实如此,学会dfs和bfs暴力搜索枚举确实利用 ...

  8. 数据结构与算法—图论之dfs、bfs(深度优先搜索、宽度优先搜索)

    文章目录 前言 邻接矩阵和邻接表 深度优先搜索(dfs) 宽度(广度)优先搜索(bfs) 总结与比较 前言 在有向图和无向图中,如果节点之间无权值或者权值相等,那么dfs和bfs时常出现在日常算法中. ...

  9. 列出连通集 (25 分)【DFS与BFS模板】

    立志用最少的代码做最高效的表达 给定一个有N个顶点和E条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访 ...

最新文章

  1. Linux下Gedit + Gmate ,实用的编辑器
  2. 【推导】【NTT】hdu6061 RXD and functions(NTT)
  3. dev chartcontrol获取x y轴的值_终于,奔驰强势接手了腾势X
  4. http error
  5. 你见过扇贝游泳吗? | 今日趣图
  6. [李景山php]每天TP5-20170125|thinkphp5-Process.php-7
  7. 消费者启动,允许期间报task supervisor timed out 异常,解决
  8. java中sql 语句格式转换_Java字符串转Sql语句In格式工具方法
  9. Oracle SQL注入常用语句
  10. 网络安全技术复习资料
  11. 修复Joe主题静态资源为国内地址
  12. android相册在哪个文件夹里,手机相册在哪个文件夹?
  13. 激光雷达运动畸变去除方法
  14. 背叛的下场,你敢不敢看
  15. 手机:运行内存,机身内存,内存卡的区分
  16. 独立之精神,自由之思想
  17. 删除word文件限制编辑密码
  18. 从小学到高中,一个程序猿的独白
  19. java冒泡排序真正最优的优化方案
  20. 气相色谱仪未来的发展趋势

热门文章

  1. 零基础学python用哪本书好-零基础学习python推荐几本书?
  2. python编程入门-Python编程:从入门到实践 PDF 中文扫描版
  3. 韩语识别_韩语文字识别_韩语图片识别 - 云+社区 - 腾讯云
  4. 四川首例 “自贡话智能语音识别系统”在检察院投用
  5. play ---------idea
  6. 查看每个用户linux内存,编写shell脚本查看linux当前各用户的cpu和memory消耗比例
  7. Express中间件(非常详细)
  8. 【动态规划】完全背包:存钱罐(恰好装满)
  9. 【动态规划笔记】状压dp:旅行商问题
  10. 网络中延迟对主观感受的影响