题目: 某公司在某地区共有六个产品销售点,销售点间的距离如下图所示。现根据业务需要计划在其中某个销售点上建立一个中心仓库,负责向其它销售点提*品。
假设每天需要向每个销售点运输一次产品且每次运输只能供应一个销售点,那么将中心仓库建在何处才能保证运输总距离最短?求出最短运输距离。
思路:
这是一个求图的中心顶点问题,即在一个带权图G中,求出一个顶点v,使得v到其余顶点的最短路径长度之和最小。首先用弗罗伊德算法求出图中各个顶点之间的最短路径长度,然后再求出每个顶点到其余各顶点的最短路径长度之和,从中选取一个最短路径长度之和最小的顶点即为要求的顶点。
各顶点最短距离:
A | B | C | D | E | F | 总和 | |
---|---|---|---|---|---|---|---|
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 |
E | 10 | 10 | 8 | 10 | \ | 7 | 45 |
F | 3 | 5 | 6 | 8 | 7 | \ | 29 |
上图的邻接矩阵表示("∞"表示不连通)
实现代码+注释
# 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;
}
运行结果: