这题目好长啊,题目大概意思就是说有一个图,然后要你求它的最小联通度(题目的定义:所有生成子图中的最大度-最小度的最小值),思路:先对所有边降序排序,用贪心思想求出所有最小生成树,然后取他们的最小联通度。在做题中我的错误:一开始我直接求最大生成树然后最大度-最小度=最小联通度,后来想了想最大生成树的最大度-最小度一定是最小联通度吗?我这个纯属瞎搞没有任何证明,引以为戒。
另外kruskal中l连通分量和查询和合并用并查集优化效率非常高,在平摊意义下,find函数试卷复杂度几乎可以看成常数,union显然是常数时间。
代码:

#include<bits/stdc++.h>
using namespace std;
typedef struct {
	int x,y,w;
}node;
node a[5000];
const int inf=0x3f3f3f3f;
int n,m;
int f[5000];
int find_x(int x){
	if(x!=f[x]){
		f[x]=find_x(f[x]);
	}
	return f[x];
}
bool cmp(node a,node b){
	return a.w<b.w;
}
void skl(){
	int ans=inf;
	for(int i=1;i<=m;i++){
		int cnt=0;
		for(int p=1;p<=n;p++)f[p]=p;
		for(int j=i;j<=m;j++){
			int aa=find_x(a[j].x);
			int bb=find_x(a[j].y);
			if(aa!=bb){
				cnt++;
				f[aa]=bb;
			}
			if(cnt==n-1){
				int minn=a[j].w-a[i].w;
			// cout<<minn<<endl;
				ans=min(ans,minn);
				break;
			}
		}
	}
	if(ans!=inf)
	cout<<ans<<endl;
	else
	cout<<"-1"<<endl;
}
int main()
{
	while(cin>>n>>m){
		if(n==0&&m==0)break;
		memset(a,0,sizeof(a));
		for(int i=1;i<=m;i++){
			cin>>a[i].x>>a[i].y>>a[i].w;
		}
		sort(a+1,a+1+m,cmp);
		skl();
	}
}