问题:
给定一个无向图,求它的一棵生成树,使得生成树中的最大边权与最小边权 的差最小,输出其最小差值。
输入:
第一行两个整数 n(2接下来 m 行,第 i+1 行包含三个整数 Xi(0保证图是连通的,两个点之间最多只有一条边。
输出:
包含一行,表示最小差值生成树的最大边与最小边的差值。
样例:
3 3
1 2 10
1 3 20
2 3 30
、、、、、
10
炸一看,最小生成树嘛,就用“克鲁斯卡尔”算法求吧,不过既然要求最大边与最小边差值最小,不用想太多,直接对边从小到大排序之后,每次从第一最小,第二最小。。。开始讨论,计入插入边的cnt,当cnt=n-1 表示找到一个生成树,用ans记录一下差值即可。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=204;
const int maxm=5050;
const int inf=1e9;
struct node{
int u,v,w;
}edge[maxm];
int n,m,i,j,father[maxn];
int cmp(node a,node b){return a.w<b.w;}
void init()
{
for(i=1;i<=n;i++)father[i]=i;
}
int getfather(int x)
{
return x==father[x]? x : father[x]=getfather(father[x]);
}
int merge(int x,int y)
{
int fx=getfather(x);
int fy=getfather(y);
if(fx!=fy){father[fx]=fy;return 1;}
return 0;
}
int main()
{
int ans=inf;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
sort(edge,edge+m,cmp);
for(int i=0;i<m;i++)
{
int cnt=0;
init();
for(int j=i;j<m;j++)
{
if(merge(edge[j].u,edge[j].v))cnt++;
if(cnt==n-1)
{
ans=min(ans,edge[j].w-edge[i].w);
break;
}
}
}
if(ans==inf)ans=-1;
printf("%d",ans);
}