第7章 图——最小生成树之普利姆算法

来源:互联网 发布:mysql 日期大于等于 编辑:程序博客网 时间:2024/06/09 15:31
/* *  这个程序是用普利姆算法生成一个有向图的最小生成树, *  并按照生成顺序打印出这个最小生成树每条边的起始点。 *  无向图的信息参照课本P174的图7.16 。 */#include<stdio.h>  #define MAX 100000typedef struct Mgraph{int edges[10][10]; /*边信息。*/}Mgraph;  int createudg(Mgraph *G,int n,int e){ /*创建一个无向图。*/  int i,a,b,value,j;      for(i = 0;i<=n-1;i++){          for(j = 0;j<=n-1;j++)              G->edges[i][j] = MAX;    }      for(i = 1;i<=e;i++){          scanf("%d%d%d",&a,&b,&value); /*存储每条边的起始点、权值。*/          G->edges[a-1][b-1] = G->edges[b-1][a-1] = value; /*顶点序号从 1 开始,和对应下标差 1 。*/      }      return 0;  }  int prim(Mgraph *G,int n){ /*普利姆算法。*/      int i,dis[10],visit[10],j,index,a[10],b[10],g[10],m[10],t,max;      for(i = 0;i<=n-1;i++){/*初始化各顶点不连通,*/          dis[i] = MAX; /*且都未被访问过。*/          visit[i] = 0;      }      dis[0] = 0; /*初始化最小生成树的源点。*/       t = 0;       for(i = 0;i<=n-1;i++){         max = MAX;    for(j = 0;j<=n-1;j++){ /*此循环第一次是用来定源点,*/     if(visit[j]==0&&dis[j]<max){ /*之后是用来确定和前一个确定的顶点之间权值最小的点。*/     index = j;     max = dis[j];     }     }     visit[index] = 1;/*新确定的顶点。*/     if(index!=0){     g[t] = b[index]; /*把顶点的序号放进数组,*/     m[t] = a[index]; /*第一次自己到自己不需要存储。*/     t++;     }     for(j = 0;j<=n-1;j++){     if(visit[j]==0&&G->edges[index][j]<dis[j]){ /*找到刚确定的点和未确定的点之间的权值最小的边。*/   dis[j] = G->edges[j][index];     a[j] = j+1; /*记住两端的顶点。*/    b[j] = index+1;     }     }  }     for(i = 0;i<=t-1;i++)          printf("%d %d\n",g[i],m[i]); /*打印最小生成树的边。*/      return 0;  }  int main(){  Mgraph G;int n,e;    scanf("%d%d",&n,&e);createudg(&G,n,e);  prim(&G,n);   return 0;  } /* *  测试: *     输入: *        6 10 //顶点数、边数。 *        1 2 6 // 边的起始点、权值。 *        1 3 1 *        1 4 5 *        2 3 5 *        2 5 3 *        3 4 5 *        3 5 6 *        3 6 4 *        4 6 2 *        5 6 6 *     输出: *        1 3 //最小生成树各边的起始点。 *        3 6 *        6 4 *        3 2 *        2 5 */

原创粉丝点击