#include <stdio.h> #define NUM 9 //顶点数 #define MV 65536 //最大值 int p[NUM];//辅助数组,记录边的数组,下标是一个顶点,值又是另一个顶点 int cost[NUM];//记录每条边的权值 int mark[NUM];//标记数组(标记是否被标记) /*用邻接矩阵定义图,每个元素的数字代表相应边的权值,且注意邻接矩阵具有对称性*/ int matrix[NUM][NUM] = { { 0, 10, MV, MV, MV, 11, MV, MV, MV }, { 10, 0, 18, MV, MV, MV, 16, MV, 12 }, { MV, 18, 0, 22, MV, MV, MV, MV, 8 }, { MV, MV, 22, 0, 20, MV, MV, 16, 21 }, { MV, MV, MV, 20, 0, 26, MV, 7, MV }, { 11, MV, MV, MV, 26, 0, 17, MV, MV }, { MV, 16, MV, MV, MV, 17, 0, 19, MV }, { MV, MV, MV, 16, 7, MV, 19, 0, MV }, { MV, 12, 8, 21, MV, MV, MV, MV, 0 }, }; /*以sv为起始顶点开始寻找最小联通网*/ void Prim(int sv) { int i = 0;//循环控制变量 int j = 0; if ((0 <= sv) && (sv < NUM)){//合法性检测 for (i = 0; i < NUM; i++){//初始化,以sv为起点到其他顶点的权值为cost数组赋值 cost[i] = matrix[sv][i]; p[i] = sv;//以sv出发,即值是一个顶点,且其他的i,即下标又是另一个顶点 mark[i] = 0;//0表示没有被标记 } mark[sv] = 1;//将选定的起始顶点先标记 for (i = 0; i < NUM; i++){//重复找最小权值的边 int min = MV; int index = -1; for (j = 0; j < NUM; j++){//真正以某一个顶点为起点找与之关联的最小权值的边 if ((!mark[j]) && (cost[j] < min)){//如果没有被标记,且以sv作为起始顶点到其他定点的边的权值小于min min = cost[j]; index = j;//以sv为起点找到的最小权值的边,另一顶点为index } } if (index > -1){//找到最小值 mark[index] = 1;//标记该顶点 printf("(%d,%d,%d)\n", p[index], index, cost[index]);//打印找到的边 } /*修改cost数组,因为要从新顶点出发看看是否能找更小的权的边*/ for (j = 0; j < NUM; j++){ /*用刚刚标记的顶点index作为起始顶点和那些未标记的顶点去找权值最小的边, 如果matrix[index][j] 小于ocst[j]成立,表示有可能能找到比当前cost记录的权值还要小的边, 所以更新cost使之保持最小的权值*/ if ((!mark[j]) && (matrix[index][j] < cost[j])){ cost[j] = matrix[index][j]; p[j] = index;//更新边的两个顶点 } } } } } int main() { Prim(0); system("PAUSE"); return 0; }
最小连通网
最新推荐文章于 2022-07-05 13:10:43 发布