C ++ genera una secuencia topológica de gráfico acíclico dirigido


1. Secuencia topológica

El concepto de secuencia topológica

En un gráfico acíclico dirigido, si hay un arco <i, j>, entonces en la secuencia topológica, i debe estar delante de j. Una secuencia lineal con esta propiedad se llama secuencia topológicamente ordenada.

Aplicación de secuencia topológica

(1) Se puede obtener la secuencia de ejecución de varios eventos relacionados;
(2) Se puede juzgar si hay un bucle (bucle) en un gráfico dirigido.


2. Pasos de clasificación topológica

(1) Seleccione un vértice con un grado de 0 (es decir, sin vértice predecesor) en el gráfico dirigido.

(2) Guarde el vértice en el resultado de salida, elimine el vértice y el arco conectado al vértice del gráfico.

(3) Repita los pasos (1) y (2) hasta que se hayan generado todos los vértices o no haya ningún vértice cuyo predecesor sea 0 en el gráfico.


3. Ejemplo

Inserte la descripción de la imagen aquí
Como se muestra en la figura,
(1) Seleccione el vértice v0 cuyo grado de entrada es 0, guárdelo en el resultado de la matriz y elimine v0 y el arco conectado a él.

Inserte la descripción de la imagen aquí
(2) Continúe seleccionando los vértices con in-grado 0. Puede seleccionar v3 o v1. Aquí, seleccione v1, guárdelo en el resultado de la matriz y elimine v1 y los arcos conectados a él.

Inserte la descripción de la imagen aquí
(3) Continúe seleccionando el vértice con el grado 0. Puede seleccionar v3 o v2, aquí seleccione v2, guárdelo en el resultado de la matriz, elimine v2 y el arco conectado a él.

Inserte la descripción de la imagen aquí
(4) Continúe seleccionando el vértice cuyo grado de entrada es 0, que es v3, guárdelo en el resultado de la matriz, elimine v3 y el arco conectado a él. En este momento, solo queda v4, y su grado de entrada es 0, continúe seleccionando una vez y guárdelo en el resultado de la matriz, y la clasificación finaliza.

Los datos de la matriz de resultados: 0, 1, 2, 3, 4 es una secuencia topológica.


4. Implementación del código

#include<iostream>
#include<queue>
#include<vector>
using namespace std;

#define Max 9999
int n, m; // n为顶点数,m为边数
int G[Max][Max];
int inDegree[Max];
vector<int> result;//记录结果

void topsort()
{
    
    
	queue<int> node; // 用来保存入度为 0 的顶点
	for (int i = 0; i < n; ++i)
	{
    
    
		if (inDegree[i] == 0)
		{
    
    
			node.push(i);
			inDegree[i] = -1;
		}
	}
	if (node.empty())
	{
    
    
		cout << "该图无拓扑排序" << endl;
		return;
	}
	while (!node.empty())
	{
    
     
		int temp = node.front();
		node.pop();
		for (int i = 0; i < n; ++i)
		{
    
    
			if (G[temp][i] != 0)  //删除与所选顶点相连的弧并让弧的另一个顶点入度减一
			{
    
    
				inDegree[i]--;
				G[temp][i] = 0;
			}
			if (inDegree[i] == 0)  //若顶点的入度为 0 ,则将其加入队列
			{
    
    
				node.push(i);
				inDegree[i] = -1;
			}
		}
		result.push_back(temp);
	}
	if (result.size() < n) // 判断图中的顶点是否全部加入
	{
    
    
		cout << "该图无拓扑排序" << endl;
	}
	else
	{
    
    
		cout << "该图的一个拓扑排序为:" << endl;
		for (int i = 0; i < result.size(); ++i)
		{
    
    
			cout << result[i] << " ";
		}
	}
}
int main()
{
    
    
	cout << "输入顶点数:";
	cin >> n;
	cout << "输入边数:";
	cin >> m;
	cout << "输入各边的信息:";
	fill(G[0], G[0] + Max * Max, 0);
	fill(inDegree, inDegree + Max, 0);
	int u, v; //u为前驱节点,v为后继节点
	for (int i = 0; i < m; ++i)
	{
    
    
		cin >> u >> v;
		G[u][v]++;
		inDegree[v]++;  //入度加一
	}
	topsort();

	return 0;
}

Información de entrada y salida:Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_46027243/article/details/108916705
Recomendado
Clasificación