[Algoritmo] (algoritmo de Floyd) el problema del vértice central del gráfico (lenguaje C)

Tema: Una empresa tiene seis puntos de venta de productos en una determinada región, y la distancia entre los puntos de venta se muestra en la siguiente figura. Ahora de acuerdo a las necesidades del negocio, se planea establecer un almacén central en uno de los puntos de venta, encargado de abastecer de productos a los demás puntos de venta.
Suponiendo que los productos deben transportarse a cada punto de venta una vez al día y que cada envío solo puede abastecer a un punto de venta, ¿dónde debe construirse el almacén central para garantizar la distancia de transporte total más corta? Encuentre la distancia de transporte más corta.
imagen

Idea:
Este es un problema de encontrar el vértice central de un gráfico, es decir, en un gráfico ponderado G, encontrar un vértice v tal que la suma de las longitudes de camino más cortas de v a otros vértices sea la más pequeña. Primero use el algoritmo de Floyd para encontrar la longitud del camino más corto entre cada vértice en el gráfico, y luego encuentre la suma de las longitudes del camino más corto de cada vértice a los otros vértices, y seleccione un vértice con la suma más pequeña de las longitudes del camino más corto como el vértice del requisito.

La distancia más corta de cada vértice:

A B C D mi F suma
A \ 2 3 5 10 3 23
B 2 \ 2 4 10 5 23
C 3 2 \ 2 8 6 21
D 5 4 2 \ 10 8 29
mi 10 10 8 10 \ 7 45
F 3 5 6 8 7 \ 29

La representación de la matriz de adyacencia de la figura anterior ("∞" significa desconectado)
matriz de adyacencia

Código de implementación + comentarios

# include<stdio.h>
# define VERTEX_NUM 6				//顶点个数
# define INFINITY 32768

/*图的邻接矩阵表示法*/
typedef struct {
    
    
	char vertex[VERTEX_NUM];				//顶点
	int arcs[VERTEX_NUM][VERTEX_NUM];		//邻接矩阵
	int vexnum, arcnum;						//图的顶点数和弧数
}AdjMatrix;

/*根据题中信息创建无向网*/
int CreateDN(AdjMatrix* G) {
    
    
	int i, j;
	G->vexnum = 6;							//共有6个销售点即图顶点数为6
	G->arcnum = 8;							//共有8条路径即图的弧数为8
	for (i = 0; i < G->vexnum; i++)
		G->vertex[i] = 'A' + i;
	for (i = 0; i < G->vexnum; i++) {
    
    		//初始化邻接矩阵
		for (j = 0; j < G->vexnum; j++)
			G->arcs[i][j] = INFINITY;
	}

	G->arcs[0][1] = 2;						//建立邻接矩阵
	G->arcs[0][2] = 3;
	G->arcs[0][4] = 10;
	G->arcs[0][5] = 3;
	G->arcs[1][2] = 2;
	G->arcs[2][3] = 2;
	G->arcs[2][4] = 8;
	G->arcs[4][5] = 7;

	G->arcs[1][0] = 2;
	G->arcs[2][0] = 3;
	G->arcs[4][0] = 10;
	G->arcs[5][0] = 3;
	G->arcs[2][1] = 2;
	G->arcs[3][2] = 2;
	G->arcs[4][2] = 8;
	G->arcs[5][4] = 7;
}

/*求图的中心顶点算法*/
void CenterVex(AdjMatrix G) {
    
    
	int i, j, k, min, len;
	int A[VERTEX_NUM][VERTEX_NUM];			//A[i][j]存放顶点i和j之间的最短路径长度
	for (i = 0; i < VERTEX_NUM; i++) {
    
    		//初始化A[i][j]
		for (j = 0; j < VERTEX_NUM; j++)
			A[i][j] = G.arcs[i][j];
		A[i][i] = 0;						//i到i的路径长度为0
	}
	for (k = 0; k < VERTEX_NUM; k++) {
    
    		//求出每一对顶点之间的最短路径长度(Floyd算法核心)
		for (i = 0; i < VERTEX_NUM; i++) {
    
    
			for (j = 0; j < VERTEX_NUM; j++) {
    
    
				if (A[i][k] + A[k][j] < A[i][j])
					A[i][j] = A[i][k] + A[k][j];
			}
		}
	}
	min = INFINITY;
	k = 0;
	for (i = 0; i < VERTEX_NUM; i++) {
    
    		//选择到各顶点最短路径长度之和最小的顶点vk
		len = 0;
		for (j = 0; j < VERTEX_NUM; j++)	//求vi到其余各顶点的最短路径长度之和
			len = len + A[i][j];
		if (len < min) {
    
    
			k = i;
			min = len;
		}
	}
	printf("建在%c处\n最短运输总距离为%d\n", G.vertex[k], min);
}

int main() {
    
    
	AdjMatrix G;
	CreateDN(&G);
	CenterVex(G);
	return 0;
}

resultado de la operación:
resultado de la operación

Supongo que te gusta

Origin blog.csdn.net/weixin_51450101/article/details/123119924
Recomendado
Clasificación