poj 3522 Slim Span(最小生成树 Kruskal算法)

来源:互联网 发布:软件开发工作 编辑:程序博客网 时间:2024/04/28 08:49

题意:求一个图的生成树中若干生成树的最大边和最小边的最小差值

换个角度想就是用n-1条(n个点)数值相差不多的边,组成一棵生成树。
在生成树的prim和kruskal两个算法中很容易就会觉得kruskal的贪心思想会更加适合这道题。
kruskal算法一开始会对边进行排序,然后枚举最小的边。


#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int INF=999999;const int MaxNode=100;const int MaxEdge=10003;struct edge{    int a,b,w;}edge1[MaxEdge];bool cmp(const edge&a,const edge&b){    return a.w<b.w;}int p[MaxNode+1],rank1[MaxNode+1];int makeSet(int n)//初置并查集{    for(int i=1;i<=n;i++)    {        p[i]=i;        rank1[i]=0;    }}int findSet(int x)//{    if(x!=p[x])        p[x]=findSet(p[x]);    return p[x];}int unionSet(int x,int y){    if(rank1[x]>rank1[y])        p[y]=x;    else    {        p[x]=y;        if(rank1[x]==rank1[y])++rank1[x];    }}int main(){    int n,m;    while(scanf("%d%d",&n,&m)&&(n||m))    {        int i,a,b,w;        for(i=0;i<m;i++)            scanf("%d%d%d",&edge1[i].a,&edge1[i].b,&edge1[i].w);        sort(edge1,edge1+m,cmp);        int smallest=INF;        for(i=0;i<m;i++)        {            makeSet(n);            int maxWeight=-INF;            int minWeight=INF;            int k=i,number=n-1;            while(k<m&&number)            {                int fx=findSet(edge1[k].a);                int fy=findSet(edge1[k].b);                if(fx!=fy)                {                    number--;                   maxWeight = max(maxWeight, edge1[k].w);                   minWeight = min(minWeight, edge1[k].w);                   unionSet(fx, fy);                }                k++;            }             if(number) break; //从第i条边到最后一条边不能再连成一棵生成树,故退出                smallest = min(smallest, maxWeight - minWeight);        }         if(smallest == INF) printf("-1\n");//不能构成生成树            else printf("%d\n", smallest);    }}


1 0
原创粉丝点击