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.
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)
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: