kruskal算法求最小生成树

kruskal算法是一种使用贪心思路求解无向图的最小生成树的算法。

其大体思路为:将边按权重排序,然后每次选出权最小且不使图产生环的边,作为树的边挂上树。


具体来讲就是这么两个步骤:

          1.把边按权重排序。

          2.依照1的顺序遍历边:

                    使用一个并查集来判断加进这条边后图中是否有环。

                    如果没有环,更新并查集,并把此边加入树。


并查集判断环的回顾:

          使用一个数组保存每个点的祖先节点。对于无向图,可以直接按照点的数字大小作为代表元的依据,令值小的为代表元。

         如果两个点v,w,判断加入新边e=<v,w>后是否会产生环的思路是:如果v,w加边前的代表元相同,那么就说明v,w间有路,加边后就会成环。


变量使用: 使用edg[]{v1,v2,w}记录每个边的信息,fa[]为并查集,v,e代表图的节点,边数。

       


以hdu1301为例

#include <bits/stdc++.h>
using namespace std;
const int maxn=200;
struct ed
{
    int v1,v2,w;
    bool operator <(const ed b) const{return w<b.w;}
}edg[maxn];
int v,e,fa[maxn];
int findfa(int pos)
{
    if(fa[pos]==pos)return pos;
    return findfa(fa[pos]);
}
void init()
{
    memset(edg,0,sizeof(edg));
    char c;
    int si,cu;
    e=1;  fa[v]=v;
    for(int i=1;i<v;i++)
    {
        fa[i]=i;
        cin>>c>>si;
        while(si--)
        {
            cin>>c>>cu;
            edg[e].v1=i;
            edg[e].v2=c-'A'+1;
            edg[e].w=cu;
            e++;
        }
    }

    sort(edg+1,edg+e);
}
int kruskal()
{
    int su=0;
    for(int i=1;i<=e;i++)
    {
        int vs=findfa(edg[i].v1),vb=findfa(edg[i].v2);
        if(vs!=vb)
        {
            fa[vb]=vs;
            su+=edg[i].w;
        }
    }
    return su;
}
int main()
{
    while(cin>>v,v!=0)
    {
        init();
        cout<<kruskal()<<endl;
    }
    return 0;
}





 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值