Comprensión de la estructura de datos e implementación del algoritmo Prim del árbol de expansión mínimo y árbol de expansión máximo del gráfico.

El algoritmo de Prim es un algoritmo para encontrar la suma más pequeña de pesos de todos los árboles conectados

Si la ruta tiene el valor correcto para cada ruta de comunicación entre la pluralidad de árboles
con n vértices que necesita n-1 rutas habilita que cada nodo esté conectado
, y n-1 que pondera la ruta mínima
- -----
paso 1:
inicializar una matriz asociada de coordenadas de vértice almacenada adjvex [ver]
inicializa un vértice y los derechos asociados valor de borde correspondiente almacenado en lowcost [ver]

Elija un vértice como primer punto de selección, normalmente el primer o el último vértice. Aquí seleccione el primer vértice A

Paso 2:
inicializar dos matrices

Almacene los pesos relacionados con A en la matriz lowcost [ver] (si no existe, INF es infinito) y
establezca los valores de lowcost [ver] en el subíndice 0 de A

Paso 3
Ingrese al bucle grande
{ encuentre el que tenga el menor peso del borde relacionado de A, seleccione su vértice B, marque el vértice B y escriba su posición k

Luego busque el peso alrededor de B y compárelo con la posición correspondiente del arreglo original lowcost [ver] (porque no hay conexión, es infinito), y seleccione el más pequeño para dar lowcost [ver]
(en resumen, serán las B seleccionadas seleccionadas por ponderaciones relevantes )

Luego use adjvex [ver] para registrar la posición de B en la posición del peso relevante

((Finalmente, regrese al ciclo anterior para seleccionar los pesos relacionados con B (es importante incluir también los pesos relacionados de A porque la selección de ubicación no ha sido procesada)))
}

La etiqueta se marcará cada vez que se seleccione y no se puede volver a seleccionar.

Estructura gráfica

#include<iostream>
#include <iomanip>
using namespace std;

typedef char Vertextype;//顶点类型
typedef int Edgetype;//边缘权值
typedef int Status;
#define MAXVER 9//最大顶点数
#define INF 65535//代表无穷
#define NULL 0


typedef struct Graph
{
    
    
	Vertextype Ver[MAXVER];
	Edgetype Arc[MAXVER][MAXVER];
	int NumVer, NumEdg;
}MGraph;

Status CreatGraph(MGraph &G)
{
    
    
	int i, j, k, w;
	cout << "Please enter the number of verticesof the graph : " << endl;
	cin >> G.NumVer;
	cout << "Please enter the number of edges the graph : " << endl;
	cin >> G.NumEdg;
	cout << "Please enter the name of vex : " << endl;
	for (i = 0; i < G.NumVer; i++){
    
    
		//cout << "Please enter the NO." << i + 1 << "%d name of vex : " << endl;
		cin >> G.Ver[i];
	}

	cout << "Diagonal infinity ..." << endl;
	for (i = 0; i < G.NumVer; i++)
		for (j = 0; j < G.NumVer; j++)
		{
    
    
		G.Arc[i][j] = INF;//简单图  不循环
		//cout << G.arc[i][j] << endl;//不理解为啥是1
		}
	cout << "...Diagonal infinity" << endl;

	for (int k = 0; k < G.NumEdg; k++){
    
    //因为具体哪条边存在不一定 所以选择性输入边
		cout << "Enter the subscripts and weights from vertex vi to vertex vj : " << endl;
		cin >> i >> j >> w;
		/*cout << "Please enter the subscript j of the edge : " << endl;
		cin >> j;
		cout << "Please enter the weight from vertex "<<i<<" to vertex "<<j<<" : " << endl;
		cin >> w;*/

		G.Arc[i][j] = w;
		G.Arc[j][i] = G.Arc[i][j];//无向图  边的信息  是对称的  //有向图的话 无需设置

	}
	return 0;
}

Implementación del algoritmo prim

/*prim算法生成最小生成树*/
//Lowcost数组会一直变化,初始化时是0顶点和其他顶点之间的权值(有连线就是有权值 不然为INF无穷大)
//后面LC数组会记录下被选择权重最小的那个顶点相关的权重

//Adjvex数组也会一直变化  初始化时是都是0
//会记录下顶点相关权重位置
void MinSpanTree(Graph &G)
{
    
    
	int min, i, j, k;
	int Adjvex[MAXVER];		//保存相关顶点下标
	int Lowcost[MAXVER];	//保存相关顶点间边的权值

	/*选取一个顶点 加入最小生成树,选择0是方便后面  所以选择头或尾最好*/
	Lowcost[0] = 0;			//标记为0 就是被选择 后续循环不再用该点
	Adjvex[0] = 0;			
	
	/*取Lowcost数组   存放和第一个生成树顶点相关的权值  若不存在 则默认是INF*/
	for (i = 1; i < G.NumVer; i++){
    
    
		Lowcost[i] = G.Arc[0][i];		//将和第一个生成树顶点相关的权值依次存入数组
		Adjvex[i] = 0;//初始化都为第一个顶点的坐标
	}


//开始了
//先找出第一个顶点权值最小的那个
//然后将该权值的另外一个顶点标记  且用k记录位置
	for (i = 1; i < G.NumVer; i++){
    
    
		min = INF;		//初始化最小权值为INF 
		j = 1, k = 0;	//k用来记录最小权值的边

		while (j < G.NumVer)//从第一个顶点开始寻找
		{
    
    
			if (Lowcost[j] != 0 && Lowcost[j] < min)//相当于寻找合法边 进行比较找到最小的一个
			{
    
    
				//如果边存在
				min = Lowcost[j];
				k = j;//记录最小权值的边
			}
			j++;
		}

		cout <<k <<"-----"<<Adjvex[k]<< endl;//打印最小权值的位置   但是这个Ad有什么用呢

		Lowcost[k] = 0;//将此位置的顶点标记存入最小生成树的数组中后续将不再被判断  因为顶点走过一次就想
		
		//这里是更新  LC 和Ad   将上面选择的最小的顶点  的相关权值取代之前的LC里面的值      Ad为记录位置
		for (j = 1; j < G.NumVer; j++){
    
    //循环所有顶点 
			if (Lowcost[j] != 0 && G.Arc[k][j] < Lowcost[j]){
    
    
				//没有标记过的顶点   
				Lowcost[j] = G.Arc[k][j];
				Adjvex[j] = k;
			}
		}

	}
}

Función principal

int main()
{
    
    
	Graph G;
	CreatGraph(G);
	MinSpanTree(G);
	MaxSpanTree(G);
	system("pause");
	return 0;
}

El principio del árbol de expansión máximo es el mismo, pero aquí necesitamos cambiar el INF sin ruta a infinitesimal

void MaxSpanTree(Graph &G)
{
    
    
	int max, i, j, k;
	int adj[MAXVER];
	int maxcost[MAXVER];

	maxcost[0] = 0;
	adj[0] = 0;

	//将无路径设置为无穷小
	for (i = 0; i < G.NumVer; i++)
	{
    
    
		for (j = 0; j < G.NumVer; j++)
		{
    
    
			if (G.Arc[i][j] == INF)
			{
    
    
				G.Arc[i][j] = -1;
			}
		}
	}
		

	//初始化

	for (i = 1; i < G.NumVer; i++)
	{
    
    
		maxcost[i] = G.Arc[0][i];
		adj[i] = 0;
	}

	for (i = 0; i < G.NumVer; i++)
	{
    
    
		max = 0;
		j = 1; k = 0;
		while (j < G.NumVer)
		{
    
    
			if (maxcost[j] != 0 && maxcost[j] > max)
			{
    
    
				max = maxcost[j];
				k = j;
			}
			j++;
		}

		cout << k << "----" << adj[k] << endl;
		maxcost[k] = 0;//标记
		for (j = 1; j < G.NumVer; j++)
		{
    
    
			if (maxcost[j] != 0 && G.Arc[k][j] > maxcost[j])
			{
    
    
				maxcost[j] = G.Arc[k][j];
				adj[j] = k;
			}
		}
	}
}

Supongo que te gusta

Origin blog.csdn.net/weixin_46096297/article/details/113529462
Recomendado
Clasificación