poj3522 Kruskal生成树变形

题意:求一个图所有生成树中 最大边与最小边的差的最小值。

解题思路:要求max-min的最小值 就是要让max最小 min 最大。 而我们的kruskal算法求得的当前生成树的max一定是最小的。所以我们只要将min从小到大遍历,然后求得最小值即可。(语言表达的有点绕口,建议参照代码结合着看)。

#include "iostream"
#include "algorithm"
using namespace  std;
#define MAXSIZE 6000
#define  INF 100000
struct node{
	int u;
	int v;
	int w;
};
node edge[MAXSIZE];
int f[MAXSIZE];
int e;
int n,m;
void addnode(int u,int v,int w)
{
	edge[e].u=u;
	edge[e].v=v;
	edge[e].w=w;
	e++;
}
bool cmp(node &a,node &b)
{
	return a.w<b.w;
}
int findeset(int x)
{
	if(x==f[x])
		return x;
	else 
		return f[x]=findeset(f[x]);
}
int kruskal(int s)
{
	int i;
	for (i=1;i<=n;i++)
	{
		f[i]=i;
	}
	int fnum=n;//集合个数
	for (i=s;i<e;i++)
	{
		if (findeset(edge[i].u)!=findeset(edge[i].v))//不属于同一集合
		{
			//union
			f[findeset(edge[i].v)]=findeset(edge[i].u);
			fnum--;
			if (fnum==1)//合并完成
			{
				return edge[i].w-edge[s].w;
			}
		}
	}
	return INF;//无法得到一颗生成树
	
}
int main()
{
	//freopen("in.txt","r",stdin);
	while(true)
	{
		e=0;
		scanf("%d%d",&n,&m);
		if ((n==0)&&(m==0))
		{
			break;
		}
		int a,b,c;
		while(m--)
		{
			scanf("%d%d%d",&a,&b,&c);
			addnode(a,b,c);
		}
		
		//求所有生成树中 最大边与最小边差的最小值  max-min 最小 要max 最小 min 最大 
		//而kruskal 方法中求得的生成树 max一定是最小 所以我们只要min从小到大取值即可
		//
		sort(edge,edge+e,cmp);
		int ans=INF;
		for (int i=0;i<e;i++)
		{
			int t =kruskal(i);
			if (t<ans)
			{
				ans=t;
			}
		}
		if (ans!=INF)
		{
			printf("%d\n",ans);
		}
		else
		{
			printf("-1\n");
		}
		
	}
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值