题意;
给你一个无向,求所有生成树中,最大边与最小边差值最小的那个值。
算法分析:
排序,从最小边开始,枚举每一条最小边,然后求最小生成树,求差值,然后求出最小值。
代码;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define nMax 105
#define inf 0x7fffffff
struct EDGE
{
int u,v,w;
}edge[nMax * nMax / 2];
int cmp(const void *a, const void *b)//排序
{
struct EDGE *c = (struct EDGE *)a;
struct EDGE *d = (struct EDGE *)b;
return c->w - d->w;
}
int n,m;
int father[nMax],rank[nMax];
void init()//并查集初始化
{
for (int i = 1; i <= n; ++ i)
{
father[i] = i;
rank[i] = 0;
}
}
int find(int x)//并查集找父节点
{
if (x != father[x])
{
father[x] = find(father[x]);
}
return father[x];
}
void unions(int x, int y)//并查集合并
{
x = find(x);
y = find(y);
if (rank[x] > rank[y])
{
father[y] = x;
}
else
{
father[x] = y;
if (rank[x] == rank[y])
{
rank[y] ++;
}
}
}
int main()
{
while (scanf("%d %d", &n, &m) && n)
{
for (int i = 0; i < m; ++ i)
{
scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].w);
}
qsort(edge, m, sizeof(edge[0]), cmp);
int ans = inf;
for (int i = 0; i < m - n + 2; ++ i)//枚举每一条最小边,由于生成树最少要n-1条边,这里i后面至少要保证有n-1条边
{
init();
int num = 0;
for (int j = i; j < m; ++ j)//对于每一条最小边,在此基础上求最小生成树,求差值
{
if (find(edge[j].u) != find(edge[j].v))
{
unions(edge[j].u, edge[j].v);
num ++;
if (num == n - 1)//如果已经n-1条边了,证明已经n个点了,不用再求了,已经找到最小生成树了,直接break,同时更新最小值
{
if (ans > edge[j].w - edge[i].w)
{
ans = edge[j].w - edge[i].w;
}
break;
}
}
}
}
if (ans != inf)
{
printf("%d\n", ans);
}
else
printf("-1\n");
}
return 0;
}