POJ 1861题
//最小生成树:Kruskal算法
#include <stdio.h>
#include <algorithm>
using namespace std;
#define arraysize 15001
#define nodenum 1001
typedef struct node
{
int start; //起点
int end; //终点
int w; //费用
};
node edges[arraysize]; //存储边
node record[arraysize]; //存储最小生成树中的边
int final[nodenum]; //存储该点的双亲节点
int r[nodenum]; //存储以nodenum为根的树的节点数(包括根)
bool cmp(node a,node b)
{
return a.w<b.w;
}
int findroot(int n) //找到n的根节点
{
if(final[n] == n)
return n;
else
{
final[n] = findroot(final[n]);
}
return final[n];
}
int main()
{
//freopen("1.txt","r",stdin);
int N,M;
while(scanf("%d%d",&N,&M)!=EOF)
{
int start,end,w;
for(int i=1;i<M+1;++i)
{
scanf("%d%d%d",&start,&end,&w);
edges[i].start = start;
edges[i].end = end;
edges[i].w = w;
}
//Kruskal算法,初始化,建立n棵树
for(int i1=1;i1<N+1;i1++)
{
final[i1] = i1;
r[i1] = 1;
}
//对边进行排序
sort(edges+1,edges+M+1,cmp); //此处第一个参数是edges+1,第二个参数是edges+M+1
int flag = 0; //记录最小生成树中的边数
int maxLength = 0; //记录最小生成树种的最大边
//遍历所有的边
for(int i2=1;i2<M+1;++i2)
{
int a = edges[i2].start;
int b = edges[i2].end;
int w = edges[i2].w;
//查找边的源点的根节点
int roota = findroot(a);
//查找边的终点的根节点
int rootb = findroot(b);
//如果边的源点和边的终点不在同一连通子图中,则将该点加入到最小生成树中
if(roota != rootb)
{
flag++;
record[flag].start = a;
record[flag].end = b;
record[flag].w = w;
if(record[flag].w>maxLength)
{
maxLength = record[flag].w;
}
if(r[roota]>=r[rootb])
{
final[rootb] = a;
r[roota] += r[rootb];
}
else
{
final[roota] = b;
r[rootb] += r[roota];
}
}
if(flag == N-1) //找到了最小生成树
{
printf("%d\n%d\n",maxLength,flag);
for(int j=1;j<=flag;++j)
{
printf("%d %d\n",record[j].start,record[j].end);
}
break;
}
}
}
return 0;
}