【Topologische Sortierung】|Graphentheorie|Topologische Sortierung basierend auf BFS/DFS|Out-Grad In-Grad

1. Das Konzept der topologischen Sortierung

Topologische Sortierung bezieht sich auf einen Algorithmus zum Sortieren eines gerichteten azyklischen Graphen (DAG). Tatsächlich handelt es sich dabei um den Prozess der Sortierung der Knoten im Diagramm nach Priorität. Es besteht kein Grund zur Sorge, dass die vordere und hintere Sortierung dieselbe Priorität haben, und dies ist im Wesentlichen möglich.

Der Lösungsprozess der topologischen Sortierung:
Wir müssen einige Grundkenntnisse verstehen, zunächst das Konzept des Ein- und Austritts

Out-Grad: Die Anzahl der Einwegkanten, die von diesem Punkt ausgehen.
In-Grad: Die Anzahl der Einwegkanten, die von diesem Punkt ausgehen

2, Realisierung der topologischen Sequenz von BFS

Unabhängig von der Art der Operation handelt es sich um eine Kombination aus BFS- und Graphenerstellungsoperation

1. BFS implementiert topologische Sequenzen auf zwei Arten

Bei der ersten Methode müssen wir beim Out-Grad von 0 beginnen und ein In-Grad-Array für die Suche in positiver Reihenfolge erstellen.

Algorithmusidee
Dieser Algorithmus ist eine Folge von Diagrammen. Im ersten Schritt müssen wir den Speichervorgang des Diagramms abschließen . Wir wählen den einfachsten Speichervorgang des Diagramms und die
Adjazenztabellenspeicherung verwendet die Operation zum Erstellen von Kanten, um die Speicherung abzuschließen des Baumes.

Der zweite Schritt ist der Prozess von BFS . Zuerst müssen wir den Anfangsknoten verarbeiten. Wir durchlaufen alle Knoten auf einer Seite und speichern alle Knoten, deren Ingrad Null ist, in der Warteschlange, um den ersten Schritt von BFS abzuschließen . Dann müssen wir nur noch die unteren Knoten in der Warteschlange einzeln finden, und dann schließen wir den Vorgang des Subtrahierens des In- Grades dieser Knoten ab und schieben dann den Punkt mit einem Grad von 0 in die Warteschlange. Wenn die Warteschlange ist leer. Die Extraktion der Warteschlange ist abgeschlossen.

Beachten Sie, dass es sich bei der von uns verwendeten Warteschlange um eine simulierte Warteschlange handelt. Da wir die Ausgabe der Warteschlange später abschließen, führt die Verwendung des Warteschlangenelements in STL dazu, dass die Ausgabe des Warteschlangenelements fehlschlägt, sodass wir es nicht auswählen.

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std ;

const int N = 1e5 + 10 ;

int n , m ; 
int ne[N] ,e[N] ,idx , h[N] ;
int re_p[N] ;
int q[N] ;
void add(int a ,int b )
{
    
    
   e[++ idx ] = b ,ne[idx] = h[a] , h[a] = idx ;
}

bool topsort ()
{
    
    
   int tt = - 1 , hh = 0 ;
   for(int i = 1 ; i <= n ; i ++ )
   {
    
    
   	 if(!re_p[i])
   	 	q[++ tt ] = i ; 
   }
   while ( hh <= tt )
   {
    
    
   	int  t = q[hh] ;
   	hh ++ ; 
   	for(int i = h[t] ; i != - 1 ; i = ne[i])
   	{
    
    
   		int x = e[i] ;
   		if(-- re_p[x] == 0)
   			q[++ tt] = x ;
   	}
   }
   return tt == n - 1 ; 
}

int main ()
{
    
    	
   memset( h , - 1 ,sizeof h ) ;
   cin >> n >> m ;
   for(int i = 0 ; i < m ; i ++ )
   {
    
    
   	int a, b ;
   	cin >> a >> b ;
   	add(a , b ) ;
   	re_p[b] ++ ;
   }
   if(!topsort())
   	cout << -1 ;
   else 
   	for(int i = 0 ;i < n ; i ++ )
   		cout << q[i] << " ";
   	cout << endl ; 
   return 0 ;
}

Die zweite Denkweise: Wenn man von außen nachdenkt, ist dieser Ansatz zunächst einmal nicht günstig. Da der Grad als Standard verwendet wird, benötigen wir einen Backtracking-Prozess, das heißt, wir erstellen entweder direkt eine Backtracking-Umkehrkante oder wir müssen eine weitere Backtracking-Methode hinzufügen. Die Idee ist ungefähr dieselbe, aber schwieriger zu denken um.

nicht empfohlen,
nicht empfohlen,
nicht empfohlen


#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std ;

const int N = 1e5 + 10 ;

int n , m ; 
int ne[N] ,e[N] ,idx , h[N] ;
int re_p[N] ;
int q[N] ;
void add(int a ,int b )
{
    
    
	e[++ idx ] = b ,ne[idx] = h[a] , h[a] = idx ;
}

bool topsort ()
{
    
    
	int tt = - 1 , hh = 0 ;
	for(int i = 1 ; i <= n ; i ++ )
	{
    
    
		 if(!re_p[i])
		 	q[++ tt ] = i ; 
	}
	while ( hh <= tt )
	{
    
    
		int  t = q[hh] ;
		hh ++ ; 
		for(int i = h[t] ; i != - 1 ; i = ne[i])
		{
    
    
			int x = e[i] ;
			if(-- re_p[x] == 0)
				q[++ tt] = x ;
		}
	}
	return tt == n - 1 ; 
}

int main ()
{
    
    	
	memset( h , - 1 ,sizeof h ) ;
	cin >> n >> m ;
	for(int i = 0 ; i < m ; i ++ )
	{
    
    
		int a, b ;
		cin >> a >> b ;
		add(b , a ) ;
		re_p[a] ++ ;
	}
	if(!topsort())
		cout << -1 ;
	else 
		for(int i = n - 1 ;i >= 0 ; i -- )
			cout << q[i] << " ";
		cout << endl ; 
	return 0 ;
}

3, DFS und topologische Sequenz

Algorithmusidee
Die rekursive Idee von DFS ist auch in der Leistung dieser topologischen Sequenz sehr überlegen. Im Allgemeinen wird die zweite Idee von DFS und BFS auch basierend auf dem Out-Grad von Null berechnet, daher ist diese Implementierungsmethode tatsächlich Dies wird nicht empfohlen, kann aber realisiert werden. Die Implementierung ist zunächst einmal die Art und Weise der Implementierung. Da DFS die Idee einer verschachtelten Rekursion ist, wird die Idee gewählt, den Out-Grad-Segmentierungspunkt auszuwählen.

Ich denke du magst

Origin blog.csdn.net/wen030803/article/details/131901205
Empfohlen
Rangfolge