zoukankan      html  css  js  c++  java
  • 最小生成树

    1)prim算法

    算法思想:

    1、设图G的顶点集为U,从集合U中任取一点a加入顶点集V中选,a点作为起始点。

    2、在剩下的集合U中寻找一点b,使得b到集合V的权值最小,将b加入集合V

    3、反复第2部直到所有的顶点加入集合V中,此时就得到一颗最小生成树

    注:代码顶点编号为0~n-1

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    
    #define maxn 1010
    #define INF 0x3f3f3f3f
    int map[maxn][maxn];
    int mincost[maxn];
    int vis[maxn];
    
    void setmap(int m)
    {
        int a,b,cost;
        memset(map,INF,sizeof(map));
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&a,&b,&cost);
            if(cost<map[a][b])
                map[a][b]=map[b][a]=cost;
        }
    }
    
    int prim(int n)
    {
        for(int i=0;i<n;i++)
        {
            mincost[i]=INF;
            vis[i]=0;
        }
        mincost[0]=0;
        int res=0;
        while(true)
        {
            int pos=-1;
            for(int i=0;i<n;i++)
                if(!vis[i] && (pos==-1 || mincost[i]<mincost[pos]))
                pos=i;
            if(pos==-1) break;
            vis[pos]=1;
            res+=mincost[pos];
            for(int i=0;i<n;i++)
                if(!vis[i] && mincost[i]>map[pos][i])
                    mincost[i]=map[pos][i];
        }
        return res;
    }
    
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            setmap(m);
            cout<<prim(n)<<endl;
        }
        return 0;
    }
    prim

    2)Kruskal算法

    算法思想:

    1、将所有的边的权值按从小到大排序

    2、遍历边,判断边的顶点是否在同一个集合中,如果不在同一个集合,将顶点并在一起,直到所有的顶点在同一个集合中,这是将得到一颗最小生成树

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    #define maxn 1010
    
    struct edge
    {
        int x,y,cost;
    };
    
    edge e[maxn];
    int father[maxn];
    
    bool cmp(edge a,edge b)
    {
        return a.cost<b.cost;
    }
    
    void init(int n)
    {
        for(int i=0;i<=n;i++)
            father[i]=i;
    }
    
    int getfather(int x)
    {
        if(x!=father[x])
            father[x]=getfather(father[x]);
        return father[x];
    }
    
    void Union(int x,int y)
    {
        x=getfather(x);
        y=getfather(y);
        father[y]=x;
    }
    
    int same(int x,int y)
    {
        return getfather(x)==getfather(y);
    }
    
    void setmap(int m)
    {
        for(int i=0;i<m;i++)
            scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].cost);
    }
    
    int kruskal(int n,int m)
    {
        sort(e,e+m,cmp);
        init(n);
        int res=0;
        for(int i=0;i<m;i++)
        {
            if(!same(e[i].x,e[i].y))
            {
                Union(e[i].x,e[i].y);
                res+=e[i].cost;
            }
        }
        return res;
    }
    
    
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            setmap(m);
            cout<<kruskal(n,m)<<endl;
        }
        return 0;
    }
    Kruskal
  • 相关阅读:
    jsp简单自定义标签demo展示《二》
    jsp自定义标签介绍《一》
    登陆filter
    中文乱码原因以及解决方案
    C++ 中注意,零扩展和符号位扩展
    linux下的a.out文件
    今天谈谈流,什么是IO流?
    windows下的c语言和linux 下的c语言以及C标准库和系统API
    一维数组的数组指针
    结构体指针传参与返回值
  • 原文地址:https://www.cnblogs.com/mgxj/p/5726578.html
Copyright © 2011-2022 走看看