Kruskal算法. #include "stdlib.h" #include "stdio.h" #include "string.h" #define MAX_SET_NODE_NUM 101 typedef struct _SET_NODE_ST_ { int iRoot; int iRank; }SET_NODE_ST; typedef struct _EDGE_ST_ { int iVertexX; int iVertexY; int iLen; }EDGE_ST; SET_NODE_ST gastSets[MAX_SET_NODE_NUM]; EDGE_ST gastEdge[MAX_SET_NODE_NUM*MAX_SET_NODE_NUM]; /* 初始化集合*/ void MakeSet(int viIndex) { gastSets[viIndex].iRoot = viIndex; //根据实际情况指定的父节点可变化 gastSets[viIndex].iRank = 0; //根据实际情况初始化秩也有所变化 } /* 查找x元素所在的集合,回溯时压缩路径*/ int FindSet(int viIndex) { if (viIndex != gastSets[viIndex].iRoot) { gastSets[viIndex].iRoot = FindSet(gastSets[viIndex].iRoot); //这个回溯时的压缩路径是精华 } return gastSets[viIndex].iRoot; } /* 按秩合并x,y所在的集合 按秩合并,实时更新秩。 */ void UnionSet(int viIndexX, int viIndexY) { viIndexX = FindSet(viIndexX); viIndexY = FindSet(viIndexY); if (viIndexX == viIndexY) { return; } if (gastSets[viIndexX].iRank > gastSets[viIndexY].iRank) { gastSets[viIndexY].iRoot = viIndexX; } else { if (gastSets[viIndexX].iRank == gastSets[viIndexY].iRank) { gastSets[viIndexY].iRank++; } gastSets[viIndexX].iRoot = viIndexY; } return; } int EdgeCmp(const void *a,const void *b) { if (((EDGE_ST *)a)->iLen > ((EDGE_ST *)b)->iLen) { return 1; } else { return -1; } } int MST_Kruskal(int viVertexNum,int viLineNum) { int iLoopX; int iLoopEdge; int iSum = 0; int iMinLineNum = viVertexNum-1; for (iLoopX = 0; iLoopX < viVertexNum; iLoopX++) { MakeSet(iLoopX); } qsort(gastEdge,viLineNum,sizeof(EDGE_ST ),EdgeCmp); for (iLoopEdge = 0; iLoopEdge < viLineNum; iLoopEdge++) { if (FindSet(gastEdge[iLoopEdge].iVertexX) != FindSet(gastEdge[iLoopEdge].iVertexY)) { iSum += gastEdge[iLoopEdge].iLen; iMinLineNum--; if (0 >= iMinLineNum) { break; } UnionSet(gastEdge[iLoopEdge].iVertexX,gastEdge[iLoopEdge].iVertexY); } } return iSum; } int /*AgriNet*/main(void) { int N; int iLoopX; int iLoopY; int iLineNum; int iLineLen; while (EOF != scanf("%d",&N)) { iLineNum = 0; for (iLoopX = 0; iLoopX < N; iLoopX++) { for (iLoopY = 0; iLoopY < N; iLoopY++) { scanf("%d",&iLineLen); if(iLoopY > iLoopX) { gastEdge[iLineNum].iVertexX = iLoopX; gastEdge[iLineNum].iVertexY = iLoopY; gastEdge[iLineNum].iLen = iLineLen; iLineNum++; } } } printf("%d/n",MST_Kruskal(N,iLineNum)); } return 0; }