如题:http://poj.org/problem?id=1861
题目要求给出边和权 求最大的那条边最小的最小生成树。
最大边最小,可以用克鲁斯卡尔算法。
将权排序后,一个个并入集合,期间记录最大值。直到仅剩一个集合。
#include<iostream>
using namespace std;
#define MAX 15001
typedef struct
{
int x,y;
int w;
}edge;
edge e[MAX];
edge v[MAX];
int rank[MAX];
int father[MAX];
int cmp(const void * a,const void * b)
{
return ((edge *)a)->w-((edge *)b)->w;
}
void Make_Set(int x)
{
father[x]=x;
rank[x]=0;
}
int Find_Set(int x)
{
if(x!=father[x])
father[x]=Find_Set(father[x]);
return father[x];
}
void Union(int x,int y)
{
if(x==y) return;
if(rank[x]>rank[y])
father[y]=x; // 并入较深的集合
else
{
if(rank[x]==rank[y])
rank[y]++;
father[x]=y;
}
}
int main()
{
int i,m,n,k,max;
int x,y;
scanf("%d%d",&m,&n);
for(i=0;i<n;i++)
scanf("%d %d %d",&e[i].x,&e[i].y,&e[i].w);
for(i=0;i<m;i++)
Make_Set(i);
qsort(e,n,sizeof(edge),cmp); //从小到大队权排序
k=0;
max=0;
for(i=0;i<n;i++)
{
x=Find_Set(e[i].x);
y=Find_Set(e[i].y);
if(x!=y)
{
k++;
Union(x,y);
v[k]=e[i];
if(max<e[i].w)
max=e[i].w;
}
}
printf("%d\n",max);
printf("%d\n",k);
for(i=1;i<=k;i++)
printf("%d %d\n",v[i].x,v[i].y);
return 0;
}