这个是求一个图有几个强联通分量的算法

先讲一下应该流程

首先输入一个图G,创建一个反向的图GT

图G

对图进行dfs遍历,纪录每个点结束搜索的时间p[i]

p[1]=2  p[2]=1  p[3]=5  p[4]=4  p[5]=3

接下来对GT进行dfs搜索

对图GT进行搜索的时候,先从之前纪录的时间最晚的点开始搜索

就是从点3开始搜索

若是3能在反向图中搜索到4意味着正向图中存在一条4->3的路   意思就是3和4互相抵达构成连通分量

因为是时间从晚到早  所以不存在说从中间的某个点开始的情况

意思就是不会出现下面的情况:

  对GT进行搜索

  先从2开始 搜索到1

  1之后没有点  纪录12是一个连通分量

  接下来345是一个连通分量

  但其实12不是一个连通分量

所以我们从最晚的点开始搜索来避免这种情况

接下来介绍为什么从最晚的点开始搜索能避免这种情况

一个新图 只有1、2两个点

1点是在2点之后结束搜索的

那么有两种情况  第一种是 dfs(1)->dfs(2)->dfs(2)结束->dfs(1)结束

        第二种   dfs(2)->dfs(2)结束  dfs(1)->dfs(1)结束

因为我们是从最后结束的点开始搜索

即对反向图从1开始搜索

那么假设反向图中1能搜索到2   那么说明原图的2能到达1

既然原图的2能够到达1   那么就不会出现dfs(2)->dfs(2)结束  dfs(1)->dfs(1)结束这种情况

否则为什么dfs(2)不进入dfs(1)呢

所以原图的1能够到达2

然后就是GT图   1能搜索到2   那么原图2能搜索到1   说明1和2连通

结论:按原图dfs结束时间对方向图进行搜索,搜索到的点都能够构成连通分量

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = ;
vector<int> G[maxn],G2[maxn];
int p[maxn];
bool q[maxn];
int n;
int cnt = ;
void dfs(int u);
void dfs2(int u);
int main()
{
int i,j;
char str[];
scanf("%d",&n);
for(i=;i<=n;++i)
{
scanf("%s",str+);
for(j=;j<=n;++j)
{
if(str[j] == '')
{
G[i].push_back(j);
G2[j].push_back(i);
}
}
}
memset(q, , sizeof(q));
for(i=;i<=n;++i)
dfs(i);
int sum = ;
memset(q, , sizeof(q));
for(i=n;i>=;--i)
{
if(q[p[i]] == false)
{
sum ++ ; dfs2(p[i]);
}
}
cout << sum << endl;
return ;
}
void dfs(int u)
{
q[u] = true;
for(int i=;i<G[u].size();++i)
{
if(q[G[u][i]] == false)
{
dfs(G[u][i]);
}
}
p[cnt++] = u;
}
void dfs2(int u)
{
int i;
q[u] = true;
for(i=;i<G2[u].size();++i)
{
if(q[G2[u][i]] == false)
{
dfs2(G2[u][i]);
}
}
}

kosaraju算法的更多相关文章

  1. Kosaraju 算法检测有向图的强连通性

    给定一个有向图 G = (V, E) ,对于任意一对顶点 u 和 v,有 u --> v 和 v --> u,亦即,顶点 u 和 v 是互相可达的,则说明该图 G 是强连通的(Strong ...

  2. Kosaraju 算法查找强连通分支

    有向图 G = (V, E) 的一个强连通分支(SCC:Strongly Connected Components)是一个最大的顶点集合 C,C 是 V 的子集,对于 C 中的每一对顶点 u 和 v, ...

  3. 半连通分量--Tarjan/Kosaraju算法

    一个有向图称为半连通(Semi-Connected),满足:对于图中任两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. 若满足,则称G’是G的一个导出子图. 若G’是G的导出子图,且G’半 ...

  4. Kosaraju算法---强联通分量

    1.基础知识 所需结构:原图.反向图(若在原图中存在vi到vj有向边,在反向图中就变为vj到vi的有向边).标记数组(标记是否遍历过).一个栈(或记录顶点离开时间的数组).      算法描叙: :对 ...

  5. Kosaraju 算法

    Kosaraju 算法 一.算法简介 在计算科学中,Kosaraju的算法(又称为–Sharir Kosaraju算法)是一个线性时间(linear time)算法找到的有向图的强连通分量.它利用了一 ...

  6. codevs1506传话(kosaraju算法)

    - - - - - - - - 一个()打成[] 看了一晚上..... /* 求强连通分量 kosaraju算法 边表存图 正反构造两个图 跑两边 分别记下入栈顺序 和每个强连通分量的具体信息 */ ...

  7. Kosaraju算法解析: 求解图的强连通分量

    Kosaraju算法解析: 求解图的强连通分量 欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1. 定义 连通分量:在无向图中,即为连 ...

  8. Kosaraju算法详解

    Kosaraju算法是干什么的? Kosaraju算法可以计算出一个有向图的强连通分量 什么是强连通分量? 在一个有向图中如果两个结点(结点v与结点w)在同一个环中(等价于v可通过有向路径到达w,w也 ...

  9. 7-6-有向图强连通分量的Kosaraju算法-图-第7章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第7章  图 - 有向图强连通分量的Kosaraju算法 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版>(严 ...

  10. Kosaraju算法、Tarjan算法分析及证明--强连通分量的线性算法

    一.背景介绍 强连通分量是有向图中的一个子图,在该子图中,所有的节点都可以沿着某条路径访问其他节点.强连通性是一种非常重要的等价抽象,因为它满足 自反性:顶点V和它本身是强连通的 对称性:如果顶点V和 ...

随机推荐

  1. BZOJ1051或洛谷2341 [HAOI2006]受欢迎的牛

    BZOJ原题链接 洛谷原题链接 显然在一个强连通分量里的奶牛都可以相互喜欢,所以可以用\(tarjan\)求强连通并缩点. 要求明星奶牛必须被所有人喜欢,显然缩点后的图必须满足只有一个点没有出度,因为 ...

  2. 采用JavaMelody监控Tomcat服务——安装手册

    #1.获取安装包 .zip mv probe.war <tomcat dir>/webapps #3.设置tomcat用户信息 vi <tomcat dir>/conf/tom ...

  3. Python之线程与进程

    今天我们来了解一下Python的线程和进程的管理机制 首先,我们要了解下线程跟进程的概念: 线程(Thread)是操作系统能够进行运算调度的最小的单位,是一堆cpu的指令.他被包含在进程中,是进程中的 ...

  4. android模拟器不能上网设置

    进行sdk目录中的platform-tools目录: adb devices 系统会罗列出所有设置 adb -s emulator- shell 最后设置网关 setprop net.dns1 192 ...

  5. viewer.js使用

    viewer GitHub 地址: JS 版本:https://github.com/fengyuanchen/viewerjs jQuery 版本:https://github.com/fengyu ...

  6. 【Linux】Tree命令安装和使用

    Tree命令简介 tree是一种递归目录列表命令,产生一个深度缩进列表文件,这是彩色的ALA dircolors如果ls_colors设置环境变量和输出是TTY.树已经被移植和报道以下操作系统下工作: ...

  7. MZOJ 1345 hero

    一道宽搜模版题,可写错了两个地方的我只得了56(掩面痛哭) http://10.37.2.111/problem.php?id=1345 先看看正确的 #include <bits/stdc++ ...

  8. 62.Xcode 添加代码块

    1. Xcode创建一个新项目,打开一个.h或者.m文件 2.我举例以设置属性为例 #import <UIKit/UIKit.h> @interface ViewController : ...

  9. 686. Repeated String Match

    方法一.算是暴力解法吧,拼一段找一下 static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); cl ...

  10. 2019.01.02 NOIP训练 三七二十一(生成函数)

    传送门 生成函数基础题. 题意简述:求由1,3,5,7,9这5个数字组成的n位数个数,要求其中3和7出现的次数都要是偶数. 考虑对于每个数字构造生成函数. 对于1,5,9:∑nxnn!=ex\sum_ ...