最小生成树(Kruskal)

来源:互联网 发布:ubuntu更新 编辑:程序博客网 时间:2024/05/20 11:52
在一张图上有N个点,点与点之间的连接的花费都已经告诉你了,请你设计一下,如果解决这个“最小生成树”的问题。


 


输入


首先输入一个数字N(0〈=N〈=100)


然后输入一个N*N的矩阵 其中第i行第j列的数字k表示从点i到点j需要的花费。


 


输出


一个数字,最少需要多少花费才能使得整张图任意两点都直接或者间接连通(也就是最小生成树的权)


 


Sample Input


5


0 41 67 34 0 


41 0 69 24 78 


67 69 0 58 62 


34 24 58 0 64 


0 78 62 64 0


 


0


 


2


0 1


1 0


 


 


 


Sample Output


116


0


1


#include<iostream>#include<algorithm>using namespace std;#define MAX 101struct TEdge{int nFrom;int nTo;int nCost;};void vInit(int nArr[],int nN);int nInput(TEdge tArr[],int nN);void vSort(TEdge tArr[],int nE);bool bCmp(const TEdge &tA,const TEdge &tB);int nKruskal(TEdge tArr[],int nArr[],int nN);void vOut(int nOut);void vMerge(int nArr[],int nA,int nB,int nN);int main(){TEdge tEdges[MAX*(MAX-1)/2+1];int nOwner[MAX];int nNodes,nEdges;int nAns;while(cin>>nNodes){vInit(nOwner,nNodes);nEdges=nInput(tEdges,nNodes);vSort(tEdges,nEdges);nAns=nKruskal(tEdges,nOwner,nNodes);vOut(nAns);}return 0;}void vInit(int nArr[],int nN){int i;for(i=1;i<=nN;i++){nArr[i]=i;}}int nInput(TEdge tArr[],int nN){int nRet;int i,j,nC;nRet=0;for(i=1;i<=nN;i++){for(j=1;j<=nN;j++){cin>>nC;if(i<j){nRet++;tArr[nRet].nFrom=i;tArr[nRet].nTo=j;tArr[nRet].nCost=nC;}}}return nRet;}void vSort(TEdge tArr[],int nE){sort(&tArr[1],&tArr[nE+1],bCmp);}bool bCmp(const TEdge &tA,const TEdge &tB){return tA.nCost<tB.nCost;}int nKruskal(TEdge tArr[],int nArr[],int nN){int nRet;int nF,nT;int nFSet,nTSet;int nEdgeCount,nCount;nRet=0;nEdgeCount=1;nCount=nN;while(nCount>1){nF=tArr[nEdgeCount].nFrom;nT=tArr[nEdgeCount].nTo;nFSet=nArr[nF];nTSet=nArr[nT];if(nFSet!=nTSet){nRet+=tArr[nEdgeCount].nCost;vMerge(nArr,nFSet,nTSet,nN);nCount--;}nEdgeCount++;}return nRet;}void vOut(int nOut){cout<<nOut<<endl;}void vMerge(int nArr[],int nA,int nB,int nN){int i;for(i=1;i<=nN;i++){if(nArr[i]==nB){nArr[i]=nA;}}}


0 0
原创粉丝点击