poj 3763:Slim Span

题目链接:

点击打开链接

题意:给出一个n(n<=100)结点的图,求苗条度(最大边减最小边的值)尽量小的生成树,输出这个值。
分析:根据Kruskal算法,我们可以枚举最小边权,然后求最小生成树,就可以暴力算出最大边权减去最小边权的最小值。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 0x7f7f7f7f
struct node
{
	int st,en,len;
}E[10000];
int fa[10000];int maxx,minn,min1,n,m;
int find(int x)
{
	if(x==fa[x]) return fa[x];
	else return fa[x]=find(fa[x]);
}
bool cmp(node a,node b)
{
	return a.len <b.len;
}
int kruskal(int p)
{
	int i,j=1;
	for(i=1;i<=n;i++)
	fa[i]=i;
	maxx=0;minn=E[p].len;
	for(i=p;i<=m;i++)
	{
		int x=find(E[i].st),y=find(E[i].en);
		if(x!=y)
		{
			maxx=max(maxx,E[i].len);
			fa[x]=y;
		}
	}
	int t=find(1);
    for(i=2;i<=n;i++)
    {
      if(find(i)!=t)
	   {
		j=0;break;
	   }
   }
   if(j==0) return -1;
	else return maxx-minn;
}
int main()
{
	int i,j,temp,flag=0;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		if(n==0&&m==0) break;
		min1=inf;
		for(i=1;i<=m;i++)
		scanf("%d%d%d",&E[i].st,&E[i].en,&E[i].len);
		sort(E+1,E+m+1,cmp);
		for(i=1;i<=m-n+2;i++)///因为最小生成树边数为n-1,那么少于n-1条边肯定没有最小生成树
		{
			temp=kruskal(i);
			if(temp!=-1)
			{
				min1=min(temp,min1);
				flag=1;
			}
		}
		if(min1>=inf) flag=0;
		if(!flag) printf("-1\n");
		else printf("%d\n",min1);
	}
	return 0;
}


你可能感兴趣的:(最短路)