题意:求一个图所有生成树中 最大边与最小边的差的最小值。
解题思路:要求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;
}