http://acm.hdu.edu.cn/showproblem.php?pid=1233
/*********************最小生成树之kruskal算法**********************
// Kruskal.cpp : Defines the entry point for the console application.
*******************************************************************/
#define MAX_VERTEX_NUM 105
#define INFINITY 0x11111111
#define TRUE 1
#define FALSE 0
typedef struct{
int set; // 顶点所在集合的编号
//int info;
}VertexType;
typedef struct{
int val;
int flag; // 边的使用标记
//int info;
}ArcType,ArcMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct{
int vexnum;
VertexType vexs[MAX_VERTEX_NUM];
ArcMatrix arcs;
}MGraph;
#include <string>
#include <iostream>
using namespace std;
// 基于图的并查集操作
// ==============查
int findx(MGraph &G, int x)
{
int i,j;
int r = x;
while (G.vexs[r].set != r) //循环结束,则找到根节点
r = G.vexs[r].set;
i = x;
while (i != r) //本循环修改查找路径中所有节点
{
j = G.vexs[i].set;
G.vexs[i].set = r;
i = j;
}
return r;
}
// ==============并
void merge(MGraph &G, int x,int y)
{
int fx,fy;
fx = findx(G,x);
fy = findx(G,y);
if(fx != fy)
G.vexs[fx].set = fy;
}
int MiniSpanTree_Kruskal(MGraph &G) {
int i,j,k;
int mj,mk;
int summiniw=0;
// 初始化集合信息、边的标记值
for (i=0;i<G.vexnum;i++) G.vexs[i].set=i,G.arcs[i][i].flag=0;
for (i=1;i<G.vexnum;i++) // n-1 次 取边
{
mj=0; mk=0;
for (j=0;j<G.vexnum;j++)
for (k=0;k<G.vexnum;k++)
{
if (G.arcs[j][k].flag==INFINITY && findx(G,j)!=findx(G,k)) // 对未做标记且顶点不在同一个集合的边操作
if ( (mj==0 && mk==0) ||G.arcs[j][k].val<G.arcs[mj][mk].val ) // 最小的边
mj=j,mk=k;
}
// 合并顶点集合、标记使用过的边
merge(G,mj,mk); G.arcs[mj][mk].flag = G.arcs[mk][mj].flag = 0;
// ***************************************************************
// cout<<mj+1<<"-"<<mk+1<<": "<<G.arcs[mj][mk].val<<endl; //
summiniw+=G.arcs[mj][mk].val;
//*******************************************************************
}
return summiniw;
}
int main(int argc, char* argv[])
{
MGraph g;
int n,m;
int x,y,z;
int i;
while(scanf("%d",&n)!=EOF&&n)
{
g.vexnum = n;
memset(g.arcs,INFINITY,sizeof(g.arcs));
m=n*(n-1)/2;
for(i=0;i<m;i++)
{
cin>>x>>y>>z;
x--,y--;
g.arcs[x][y].val = z;
g.arcs[y][x].val = z;
}
printf("%d\n",MiniSpanTree_Kruskal(g));
}
return 0;
}
/************************************************************************
6 10
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6
************************************************************************/