思路:
最小生成树的性质:最短边与最长边的间距,即:最长边的权值-最短边的权值 最小
所以对这个题来说,先对所有边的权值排个序,然后分别以其中的一条边作为最短边来进行最小生成树的构造,记录每个最小生成树的结果。注意,剩下的至少要有n-1条边才能构成,所以可以稍稍剪一下枝。
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
struct edge{
int x,y,v;
}e[10010];
bool cmp(const edge &a,const edge &b){
return a.v < b.v;
}
int n,m;
int node[110];
int _find(int x){
int xx = x;
while(node[xx] != xx){
xx = node[xx];
}
int temp;
while(x != xx){
temp = node[x];
node[x] = xx;
x = temp;
}
return xx;
}
bool _merge(int x,int y){
int xx = _find(x);
int yy = _find(y);
if(xx != yy){
node[yy] = xx;
return true;
}
return false;
}
int kruskal(int ii){
for(int i = 1;i <= n;i++){
node[i] = i;
}
int cnt = 0;
int ans = e[ii].v;
int ans2;
for(int i = ii;i <= m && cnt != n-1;i++){
if(_merge(e[i].x,e[i].y)){
ans2 = e[i].v;
cnt++;
}
}
if(cnt != n-1)
return 1000000;
return ans2 - ans;
}
int main(){
int ans = 0;
while(scanf("%d%d",&n,&m),n||m){
ans = 1000000;
for(int i = 1;i <= m;i++){
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].v);
}
sort(e+1,e+1+m,cmp);
for(int i = 1;i <= m - n + 2;i++){
ans = min(ans,kruskal(i));
}
if(ans == 1000000)
ans = -1;
printf("%d\n",ans);
}
}