题目大意:n个点m条边 用n-1条边连接n个点并边权差最小
思路:枚举最小边 + Kruskal
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 105;
const int inf = 1<<30;
int n,m;
int sum;
int p[maxn];
struct node
{
int u,v,w;
}edge[maxn*maxn];
bool cmp( node a,node b )
{
return a.w < b.w;
}
int find(int x)
{
return x!=p[x]?p[x]=find(p[x]):x;
}
bool merge( int i )
{
int x = find(edge[i].u);
int y = find(edge[i].v);
if( x != y ){
p[x] = y;
sum ++;
if( sum == n-1 )
return true;
}
return false;
}
int Kruskal()
{
int ans = inf,dis;
sort(edge,edge+m,cmp); //对边从小到大排序
for( int s = 0; s <= m-n + 1; s ++ ){ //枚举最小边
sum = 0;
for( int i = 1; i <= n; i ++ )
p[i] = i;
for( int i = s; i < m; i ++ ){
if( merge(i) ){ //合并并判断是否构成n-1条边
dis = edge[i].w - edge[s].w;
ans = ans < dis?ans:dis;
break;
}
}
}
return ans == inf?-1:ans;
}
int main()
{
// freopen("data.txt","r",stdin);
int a,b,w;
while( scanf("%d%d",&n,&m) == 2,(n||m) ){
for( int i = 0; i < m; i ++ ){
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);
}
printf("%d\n",Kruskal());
}
return 0;
}