题意:求图的一个生成树使其最大边权与最小边权的差值最小,求其最小值
思路:利用贪心思想,先对边进行排序,然后从最小边开始枚举,每次进行kruskal向右加入边,若加入边刚好能遍历所有点,记录最后加入的边与第一个边的差值。最后得到最小值。
在kruskal枚举第一个边的时候没有加入判断是否剩下的边能够组成一个树,结果WA了几次,但是怎么觉得不加也没所谓呢。。?
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define MAXN 50050
#define inf 1000000000
using namespace std;
int pre[108];
int n,m,temp;int l,r;int ans;
struct Edge{
int x,y,len;
}edge[MAXN];
int cmp(Edge a,Edge b)
{
return a.len<b.len;
}
int find(int x)
{
if(x!=pre[x])
pre[x]=find(pre[x]);
return pre[x];
}
void kruskal(int x)
{
int num;
for(int i=1;i<=n;i++)
pre[i]=i;
l=edge[x].len;num=0;
//cout<<l<<endl;
for(int i=x;i<=temp;i++)
{
int a=find(edge[i].x);
int b=find(edge[i].y);
if(a!=b)
{
pre[a]=b;
num++;
}
if(num==n-1)
{
r=edge[i].len;
if(ans>r-l)ans=r-l;
//cout<<ans<<endl;
return ;
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==0&&m==0)
break;
ans=20050;
for(int i=0;i<m;i++)
{
int v,w,c;
scanf("%d%d%d",&v,&w,&c);
edge[i].x=v;
edge[i].y=w;
edge[i].len=c;
temp=i;
}
sort(edge,edge+temp+1,cmp);
//cout<<edge[0].len<<' '<<edge[temp].len<<endl;
for(int i=0;i<=temp&&m-i>=n-1;i++)
{kruskal(i);if(ans==0)break;}
if(ans!=20050)
printf("%d\n",ans);
else printf("-1\n");
}
return 0;
}