Trouvez le composant de connexion forte du graphe orienté et le résumé d'apprentissage de l'algorithme de tarjan

Qu'est-ce qu'un composant de connexion fort

Dans un graphe orienté:

1. Si deux points peuvent être connectés l'un à l'autre via une arête dirigée, alors les deux points sont appelés une connexion forte ;

2. Si deux points quelconques du graphe sont fortement connectés, alors le graphe orienté est appelé graphe fortement connecté (un point est aussi un graphe fortement connecté);

3. Un très grand sous-graphe à connexion forte dans un graphe à connexion non forte (non inclus par un autre sous-graphique à connexion forte plus grand) est appelé le composant à connexion forte de ce graphique .

Comme le montre la figure:

Les composants fortement connectés dans le graphique sont: {1,2,4} et {3}.

On constate que les composants fortement connectés présentent plusieurs caractéristiques évidentes:

1. Il n'y aura pas de points répétés dans chaque composant fortement connecté.

2. Dans un composant fortement connecté, tout point u peut passer par tous les points par l'arête dirigée, et finalement revenir au point u.

Qu'est-ce que tarjan

D'après les conclusions ci-dessus, on peut voir que le composant fortement connecté est un anneau dirigé au maximum.

Le soi-disant tarjan doit être lié à DFS (ne me demandez pas pourquoi). Supposons qu'à partir du point u DFS, si u est dans un composant fortement connecté, alors il retournera définitivement au point u à la fin.

L'implémentation spécifique de l'algorithme tarjan est:

1. Utilisez dfn [u] pour enregistrer le numéro de recherche de u (indiquant que u est le point recherché);

2. Utilisez low [u] pour représenter le point avec le plus petit numéro de recherche qui peut être recherché à partir de u, et initialisez low [u] comme dfn [u];

3. Mettez u dans la pile, et les points de la station représentent des points qui n'ont pas été classés comme composants fortement connectés;

4. Énumérer les points connectés par u et rechercher vers le bas et définir ce point comme v. Si v est dans la pile, c'est-à-dire que v a été recherché et n'est pas classé comme un composant fortement connecté, alors faible [u] = min (faible [u], dfn [v]); si v n'a pas été recherché, alors v ne doit pas être classé comme un composant fortement connecté, alors DFS [v] et enregistrez bas [u] = min (faible [u], faible [v]);

5. Enfin, si dfn [u] est égal à low [u], cela signifie que la recherche vers le bas depuis u retournera vers u (ou vers le bas depuis u), car dans la pile, le point est recherché vers le bas depuis u Ils sont tous empilés sur u, de sorte que les points empilés sur u dans la pile sont sortis de la pile avec u et classés comme un composant fortement connecté.

Parmi tous les points trouvés par u, le point qui ne peut pas être renvoyé à u par l'arête dirigée (il ne peut pas être fortement connecté à u), ou il est connecté à un point v avec une valeur dfn supérieure à u, formant un petit anneau , puis être sorti de la pile ;

Soit l'anneau n'est pas formé, la valeur basse reste la même que la valeur dfn, et elle sera sortie de la pile (c'est le composant de connexion fort d'un point),

Par conséquent, les points restants de la pile sur u sont tous des points qui peuvent être fortement connectés à u.

Par exemple, l'image ci-dessus:

Recherche à partir du point 1:

Recherche vers le bas de 2 à 4:

4 est connecté à 1, trouvé que 1 est dans la pile, les changements faibles et les retours en arrière vers 2:

Ensuite, recherchez de 2 à 3:

3 Impossible de rechercher à nouveau, dfn = low, sortez de la pile:

Enfin de retour à 1, trouvez que dfn = low, 1, 2 et 4 sont sortis de la pile ensemble:

Trouvez 2 composants fortement connectés: {3}, {1,2,4}.

code de base de tarjan

void tarjan(int x){
	dfn[x]=low[x]=IN++;
	in_s[x]=1;
	S.push(x);
	for(int i=0;i<G[x].size();i++){
		if(!dfn[G[x][i]]){
			tarjan(G[x][i]);
			low[x]=min(low[x],low[G[x][i]]);
		}
		else if(in_s[G[x][i]])low[x]=min(low[x],dfn[G[x][i]]);
	}
	if(dfn[x]==low[x]){
		num++;int v;
		do{
			v=S.top();
			S.pop();
			belong[v]=num;
			M[num]=min(M[num],mn[v]);
			in_s[v]=0;
		}while(v!=x);
	}
}

 

 

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43960287/article/details/90715320
conseillé
Classement