uva 1395 Slim Span (克鲁斯卡尔变形)

题意:生成一颗最大边和最小边之差最小的生成树,并输出差值,如果不存在输出-1

思路:将边的权升序排序,枚举[L,R],L,R为边的权,如果能够生成一颗生成树,则有Min=w[R]-w[L]。L从最小开始枚举,然后枚举R,直到生成一颗生成树,或是全部枚举完都没有生成生成树,然后L取第二小的边,R从L开始枚举,依此类推。

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 110;
int f[maxn];
struct edge
{
	int from,to,w;
}e[maxn*maxn+20];
bool cmp(edge a,edge b)
{
	return a.w<b.w;
}
int Find(int x)
{
	return f[x]==x?x:f[x]=Find(f[x]);
}
int main()
{
	int n,m; //n=[2,100]
//	freopen("in.txt","r",stdin);
	while(~scanf("%d%d",&n,&m)&&(m+n))
	{
		int i=0;
		for(i=0;i<m;i++)
		scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].w);
		sort(e,e+m,cmp);
		int ans=1<<30;
		for(i=0;i<m;i++)
		{
			for(int k=1;k<=n;k++)f[k]=k;
			int num=0;
			int mx=-1,mn=9999999;
			for(int j=i;j<m;j++)
			{
				int u=e[j].from,v=e[j].to;
				int xx=Find(u);
				int yy=Find(v);
				if(xx!=yy)
				{
					f[xx]=yy;
					num++;
					if(mx<e[j].w)mx=e[j].w;
					if(mn>e[j].w)mn=e[j].w;
					if(num==n-1)break;
				}
			}
			if(num==n-1&&ans>(mx-mn))
			ans=mx-mn;
		}
		if(ans!=1<<30)
		printf("%d\n",ans);
		else
		printf("-1\n");
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值