`
人生难得糊涂
  • 浏览: 114392 次
社区版块
存档分类
最新评论

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
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics