#include <conio.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#define INFINITY 30000 //定義一個權值的最大值#define MAX_VERTEX_NUM 20 // 圖的最大頂點數 typedef struct{int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; // 鄰接矩陣 int vexnum,arcnum; // 圖的當前頂點和邊數 }Graph;typedef struct{int adjvex;// 某頂點與已構造好的部分產生樹的頂點之間權值最小 的'頂點' int lowcost;// 某頂點與已構造好的部分產生樹的頂點之間的最小權值 }ClosEdge[MAX_VERTEX_NUM];// 用普裡姆演算法求最小產生樹時的輔助數組 int min( ClosEdge closedge, int vexnum );void CreateGraph(Graph *G);void MiniSpanTree_PRIM(Graph *G,int u);//==================================================int main(){//freopen( "in.txt", "r", stdin );Graph G; //採用鄰接矩陣結構的圖char j = 'y';int u;printf("prim 演算法構造最小產生樹,嚴格按照嚴蔚敏書上實現\n");printf("首先輸入圖的頂點數和弧數.\n格式:頂點數,弧數;例如:4,4\n");printf("接著輸入各條弧(弧尾,弧頭)和弧的權值。\n");printf("格式:弧尾,弧頭,權值;例如\n1,2,1\n1,3,2\n2,4,3\n3,4,4\n");printf("程式將會構造該圖的最小代價產生樹。\n");printf("並顯示該最小產生樹。\n1,2\n1,3\n2,4\n");while(j != 'N' && j!='n' ){CreateGraph( &G ); /* 產生鄰接矩陣結構的圖 */printf("從哪一頂點開始:");scanf( "%d", &u ); /* 輸入普裡姆演算法中的起始頂點 */MiniSpanTree_PRIM( &G, u ); /* 普裡姆演算法求最小產生樹 */printf("最小代價產生樹構造完畢,繼續進行嗎?(Y/N)");fflush(stdin); /*清除緩衝區*/scanf(" %c",&j);}return 0;}void CreateGraph(Graph *G ){/* 構造鄰接矩陣結構的圖G */ int i,j; int start,end,weight; printf("請輸入圖的頂點數和弧數:"); scanf( "%d,%d", &G->vexnum, &G->arcnum ); /* 輸入圖的頂點數和邊數 */for( i=1; i <= G->vexnum; i++ )for( j=1; j<=G->vexnum; j++ )G->arcs[i][j] = INFINITY; /* 初始化鄰接矩陣 */printf("輸入弧和其權值,格式:弧尾,弧頭,權值\n");for( i=1; i <= G->arcnum; i++ ){scanf( "%d,%d,%d", &start, &end, &weight ); /* 輸入邊的起點和終點及權值 */G->arcs[start][end] = weight; G->arcs[end][start] = weight;}/*調試代碼for( i=1; i <= G->vexnum; i++ ){for( j=1; j<=G->vexnum; j++ )printf( "%d\t", G->arcs[i][j] );printf( "\n" );}*/}void MiniSpanTree_PRIM(Graph *G,int u){/* 從第u個頂點出發構造圖G的最小產生樹 */ClosEdge closedge;int i,j,k,w;printf("最小代價產生樹:\n");for( j=1;j <= G->vexnum; j++ ) /* 輔助數組初始化 */if( j != u ) {closedge[j].adjvex = u;closedge[j].lowcost = G->arcs[u][j]; }closedge[u].lowcost=0; /* 初始,U={u} */for( i=1; i < G->vexnum; i++ ) /* 選擇其餘的(G->vexnum) - 1個頂點 */{/*調試代碼printf( "權值" );for( w = 1; w <= G->vexnum; w++ )printf( "%d ", closedge[w].lowcost );printf( "\n" );*/k = min(closedge, G->vexnum);//求出產生樹的下一個頂點printf("%d,%d\n", closedge[k].adjvex, k ); // 輸出產生樹的邊 closedge[k].lowcost=0; //第k頂點併入U集 for(j=1; j <= G->vexnum; j++) /* 新頂點併入U後,修改輔助數組*/if( G->arcs[k][j] < closedge[j].lowcost )//更新過程{//如果新併入的點和U-V的權值小於和原點集V和U-V的權值,這更新數組,採用更小的權值closedge[j].adjvex = k;closedge[j].lowcost = G->arcs[k][j];}/*調試代碼printf( "權值" );for( w = 1; w <= G->vexnum; w++ )printf( "%d ", closedge[w].lowcost );printf( "\n" );*/ }}/* 在輔助數組closedge[vexnum]中選擇權值最小的頂點,並返回其位置 */int min( ClosEdge closedge, int vexnum ){int i;int w,p;w=INFINITY;for( i=1; i <= vexnum; i++ )if( closedge[i].lowcost != 0 && closedge[i].lowcost < w ){w = closedge[i].lowcost;p=i;}return p;}