Resolver los componentes fuertemente conectados de un gráfico dirigido: algoritmo de Kosaraju

1. Introducción a componentes fuertemente conectados:
en un gráfico dirigido G, si vi,vjhay una ruta dirigida de vi a vj entre dos vértices , y también hay una ruta dirigida de vj a vi, se llamaDos vértices están fuertemente conectados. Si cada dos vértices del grafo dirigido G están fuertemente conectados, se dice que G es unGráfico fuertemente conectadoLos subgrafos fuertemente conectados de un grafo dirigido se denominan componentes fuertemente conectados

Método para resolver los componentes fuertemente conectados de la siguiente manera:
2, algoritmo de Kosaraju:
Algoritmo Basado en el hecho de que: una figura inversa G^T(con direcciones opuestas en cada lado del dibujo) y la imagen Gconectan componentes con idénticos Es decir, si el vértice. sY ten Gel Da es mutuo, si y solo si sy ten G^Tel son de la cruz.
2.1. Pasos del algoritmo y diagrama esquemático:
paso 1: primer recorrido en profundidad de la imagen original G,Registre la hora de salida de cada nodo.
Paso 2: Seleccione el vértice con la última hora de salida, G^Trecorra el gráfico inverso y elimine los vértices que se pueden atravesar Estos vértices constituyen un fuerte componente conectado.
paso 3: Si hay vértices que no se han eliminado, continúe con el paso 2; de lo contrario, el algoritmo finaliza.
Figura 1: Imagen original
Figura 1: Gráfico original G
Inserte la descripción de la imagen aquí
Figura 2: Gráfico G con dfs
Inserte la descripción de la imagen aquí
Figura 3: Gráfico inverso G ^ T
Figura 2
Figura 4: Gráfico inverso dfs, para obtener componentes conectados fuertes == (El gráfico inverso toma el último nodo de salida como el punto de partida para DFS, atravesado al Los nodos constituyen un componente fuertemente conectado) ==

2.2. Código C ++:

#include<iostream>
#include<cstring>
using namespace std;
const int MAXN=110;
int n; // 节点个数
bool flag[MAXN];//访问标志数组
int belg[MAXN];//存储强连通分量,其中belg[i]表示顶点i属于第belg[i]个强连通分量
int numb[MAXN];//结束时间标记,其中numb[i]表示离开时间为i的顶点
int G[MAXN][MAXN],GT[MAXN][MAXN]; //邻接矩阵,逆邻接矩阵
AdjTableadj[MAXN],radj[MAXN];//邻接表,逆邻接表
//用于第一次深搜,求得numb[1..n]的值
voidVisitOne(int cur,int &sig) // 访问原图
{
    
    
    flag[cur]=true;
    for(int i=0; i<n; ++i)
        if(G[cur][i] && flag[i] == false)
            VisitOne(i,sig);
    numb[++sig]=cur; //其中numb[i]表示离开时间为i的顶点
}
//用于第二次深搜,求得belg[1..n]的值
voidVisitTwo(int cur,int count) //访问逆图
{
    
    
    flag[cur]=true;
    belg[cur]=count;
    for(int i=0; i<n; ++i)
        if(GT[cur][i] && flag[i] == false)
            VisitOne(i,count);
}
//Kosaraju算法,返回为强连通分量个数
int Kosaraju_StronglyConnectedComponent()
{
    
    
    int sig=0;// sig代表离开时间
    //第一次深搜
    memset(flag,0,sizeof(bool)*n); //访问标志设为false
    for(int i=0; i<n; i++) 
        if( flag[i] == false)
            VisitOne(i,sig);
    //第二次深搜
    memset(flag,0,sizeof(bool)*n); //访问标志设为false
    int count=0; // count为强连通分量个数
    for(int i=n; i>0; --i)
        if(flag[numb[i]] == false) //频率最高的顶点若没访问
            VisitTwo(numb[i],++count);
    return count;
}

Materiales de referencia:
a. Enciclopedia Baidu: algoritmo
b de kosaraju , componente
c conectado fuerte , introducción al algoritmo sección 22.5 componente conectado fuerte

3. Algoritmo de Tarjan y algoritmo de Gabow.
No he aprendido estos dos. Si está interesado, consulte el enlace: Enciclopedia de Baidu: Componentes fuertemente conectados

para resumir:

1. Algoritmo de Kosaraju: el gráfico inverso toma el último nodo de salida como punto de partida para DFS, y los nodos atravesados ​​forman un componente conectado fuerte.

Supongo que te gusta

Origin blog.csdn.net/qq_33726635/article/details/106016480
Recomendado
Clasificación