第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 */