在一張圖上有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 stuEdg{
int nFrom ;
int nTo;
int nCost;
};
int nInput(stuEdg stuEdgs[],int nNodes);
void vSort(stuEdg stuEdgs[],int nExistEdgs);
bool bCmp(stuEdg stuEdg1,stuEdg stuEdg2);
void vInit(int nArry[],int nNodes);
int nKru(stuEdg stuEdgs[],int nArry[],int nNodes);
void vOutput(int nMin);
void vSetMerge(int nArry[],int nA,int nB,int nNodes);
int main(){
stuEdg stuEdgs[MAX*(MAX-1)/2+1];
int nNodes;
int nExistEdgs;
int nMin;
int nArry[MAX+1];
while(1==scanf("%d",&nNodes)){
nExistEdgs=nInput(stuEdgs,nNodes);
vInit(nArry,nNodes);
vSort(stuEdgs,nExistEdgs);
nMin=nKru(stuEdgs,nArry,nNodes);
vOutput(nMin);
}
return 0;
}
int nInput(stuEdg stuEdgs[],int nNodes){
int i;
int j;
int nTemp;
int nEdgCount=0;
for(i=1;i<=nNodes;i++){
for(j=1;j<=nNodes;j++){
scanf("%d",&nTemp);
if(i<j){
nEdgCount++;
stuEdgs[nEdgCount].nCost=nTemp;
stuEdgs[nEdgCount].nFrom=i;
stuEdgs[nEdgCount].nTo=j;
}
}
}
return nEdgCount;
}
void vInit(int nArry[],int nNodes){
int i;
for(i=1;i<=nNodes;i++){
nArry[i]=i;
}
}
bool bCmp(stuEdg stuEdg1,stuEdg stuEdg2){
return stuEdg1.nCost<stuEdg2.nCost;
}
void vSort(stuEdg stuEdgs[],int nExistEdgs){
sort(stuEdgs+1,stuEdgs+nExistEdgs+1,bCmp);
}
int nKru(stuEdg stuEdgs[],int nArry[],int nNodes){
int nEdgMark;
int nMin;
int nA;
int nB;
int nN;
nN=nNodes;
nEdgMark=1;
nMin=0;
while(nNodes>1){
nA=nArry[stuEdgs[nEdgMark].nFrom];
nB=nArry[stuEdgs[nEdgMark].nTo];
if(nA!=nB){
nMin+=stuEdgs[nEdgMark].nCost;
vSetMerge(nArry,nA,nB,nN);
nNodes--;
}
nEdgMark++;
}
return nMin;
}
void vSetMerge(int nArry[],int nA,int nB,int nNodes){
int i;
for(i=1;i<=nNodes;i++){
if(nArry[i]==nB){
nArry[i]=nA;
}
}
}
void vOutput(int nMin){
printf("%d\n",nMin);
}