题意:
给出一个n个结点的无向图,找一棵苗条度(最大边减去最小边)最小的生成树。图中不含重边和自环。
题解:
首先对边的权值大小排序,从小到大开始枚举最小生成树。
#include<algorithm>
#include<cstdio>
using namespace std;
struct edge
{
int u,v,w;
friend bool operator <(const edge &t1,const edge &t2)
{
return t1.w<t2.w;
}
}a[5001];
int n,m,minn,total,father[5001],tree[100];
bool check;
int find(int x)
{
if(father[x]!=x)
father[x]=find(father[x]);
return father[x];
}
void merge(int x,int y)
{
x=find(x);
y=find(y);
father[x]=y;
return;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(!n&&!m)//n顶点数量,m边的数量
break;
check=false;
minn=0x7fffffff;
for(int i=1;i<=m;++i)
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
sort(a+1,a+m+1);
for(int k=1;k<=m;++k)
{
total=0;
for(int i=1;i<=m;++i)
father[i]=i;
for(int i=k;i<=m;++i)
{
if(find(a[i].u)!=find(a[i].v))
{
tree[++total]=i;
merge(a[i].u,a[i].v);
if(total==n-1)
break;
}
}
if(total==n-1)
{
check=true;
minn=min(a[tree[total]].w-a[tree[1]].w,minn);
}
}
if(!check)
puts("-1");
else
printf("%d\n",minn);
}
return 0;
}