uva 1395 Slim Span (克鲁斯卡尔变形)

来源:互联网 发布:sh什么意思网络用语 编辑:程序博客网 时间:2024/06/14 01:52

题意:生成一颗最大边和最小边之差最小的生成树,并输出差值,如果不存在输出-1

思路:将边的权升序排序,枚举[L,R],L,R为边的权,如果能够生成一颗生成树,则有Min=w[R]-w[L]。L从最小开始枚举,然后枚举R,直到生成一颗生成树,或是全部枚举完都没有生成生成树,然后L取第二小的边,R从L开始枚举,依此类推。

#include<cstdio>#include<algorithm>using namespace std;const int maxn = 110;int f[maxn];struct edge{int from,to,w;}e[maxn*maxn+20];bool cmp(edge a,edge b){return a.w<b.w;}int Find(int x){return f[x]==x?x:f[x]=Find(f[x]);}int main(){int n,m; //n=[2,100]//freopen("in.txt","r",stdin);while(~scanf("%d%d",&n,&m)&&(m+n)){int i=0;for(i=0;i<m;i++)scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].w);sort(e,e+m,cmp);int ans=1<<30;for(i=0;i<m;i++){for(int k=1;k<=n;k++)f[k]=k;int num=0;int mx=-1,mn=9999999;for(int j=i;j<m;j++){int u=e[j].from,v=e[j].to;int xx=Find(u);int yy=Find(v);if(xx!=yy){f[xx]=yy;num++;if(mx<e[j].w)mx=e[j].w;if(mn>e[j].w)mn=e[j].w;if(num==n-1)break;}}if(num==n-1&&ans>(mx-mn))ans=mx-mn;}if(ans!=1<<30)printf("%d\n",ans);elseprintf("-1\n");}}


0 0