最小生成树(Kruskal)

在一张图上有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 101
struct 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值