读书人

图论课题训练1-K(求差值最小的生成树)

发布时间: 2013-09-28 10:01:20 作者: rapoo

图论专题训练1-K(求差值最小的生成树)

题目链接

/* *题目大意: *一个简单图,n个点,m条边; *要求一颗生成树,使得其最大边与最小边的差值是所有生成树中最小的,输出最小的那个差值; *算法分析: *枚举最小边,用kruskal求生成树,不断更新差值得到最优值;**/#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>#include<climits>#include<cstdlib>using namespace std;const int N=111;const int M=5555;const int INF=0xffffff;int n,m;int p[N];struct Edge{    int u,v,w;} e[M];int cmp(const void *a,const void *b){    Edge *x=(Edge *)a;    Edge *y=(Edge *)b;    return x->w-y->w;}int find(int x){    if(p[x]!=x)        p[x]=find(p[x]);    return p[x];}int Kruskal(int s){    int cnt=0;//记录边数    for(int i=1; i<=n; i++)        p[i]=i;    int t=s;    int flag=1;    while(t<m)    {        if(find(e[t].u)==find(e[t].v))            flag=0;        if(flag)        {            p[find(e[t].v)]=find(e[t].u);            cnt++;            if(cnt==n-1)                break;        }        t++;        flag=1;    }    if(cnt<n-1)        return -1;    return e[t].w-e[s].w;//最大边-最小边}int main(){    //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin);    while(~scanf("%d%d",&n,&m))    {        if(n==0&&m==0)            break;        for(int i=0; i<m; i++)        {            scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);        }        qsort(e,m,sizeof(Edge),cmp);        int ans=INF;        for(int i=0; i<=m-n+1; i++)//枚举所有m-n+1颗生成树        {            int res=Kruskal(i);            if(res==-1)                break;            if(res<ans)                ans=res;        }        if(ans==INF)            puts("-1");        else            printf("%d\n",ans);    }    return 0;}


读书人网 >编程

热点推荐