这题目好长啊,题目大概意思就是说有一个图,然后要你求它的最小联通度(题目的定义:所有生成子图中的最大度-最小度的最小值),思路:先对所有边降序排序,用贪心思想求出所有最小生成树,然后取他们的最小联通度。在做题中我的错误:一开始我直接求最大生成树然后最大度-最小度=最小联通度,后来想了想最大生成树的最大度-最小度一定是最小联通度吗?我这个纯属瞎搞没有任何证明,引以为戒。
另外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();
}
}