生成树-kruskal

来源:互联网 发布:淘宝开店教学书籍 编辑:程序博客网 时间:2024/05/30 04:12

 kruskal算法 解决稀疏图的最小生成树问题

 //kruskal//最小生成树保存在 边集mintree 内//返回最小生成树的权值//如果要最大生成树 把 cmp 的 '<' 改成 '>'//编号从 0 开始 到 n-1//若为二分图 将 n-1 限制 去掉 并 编号由 0~n-1 n~n+r-1;------n 图第一部分点数 r第二部分点数const int maxn=1000+10;const int maxm=15000+10;struct edge{    int u,v,w;};edge edges[maxm];edge mintree[maxm];//最小生成树边集int n,m;//点数 边数;int fa[maxn];void unset(){ms(fa,-1);}int unfind(int x){    int s;    for(s=x;fa[s]>=0;s=fa[s]);    while(s!=x)    {        int t=fa[x];        fa[x]=s;        x=t;    }    return s;}void un(int a,int b){    int r1=unfind(a),r2=unfind(b);    if(r1!=r2)    {        int t=fa[r1]+fa[r2];        if(fa[r1]>fa[r2])        {            fa[r1]=r2;            fa[r2]=t;        }        else        {            fa[r2]=r1;            fa[r1]=t;        }    }}bool cmp(edge a,edge b){    return a.w<b.w;}int kruskal(){    sort(edges,edges+m,cmp);    int sw=0;//生成树权值    int cnt=0;//已选用边数    int uu,vv;    unset();    ms(mintree,0);    fr(i,0,m-1)    {        uu=edges[i].u,vv=edges[i].v;        if(unfind(uu)!=unfind(vv))        {            mintree[cnt++]=edges[i];            sw+=edges[i].w;            un(uu,vv);        }        if(cnt>=n-1)break;    }    return sw;}/*end*/


0 0