• 最小生成树


    Kruskal算法

     Kruskal算法是基于贪心的思想得到的。首先我们把所有的边按照权值先从小到大排列,接着按照顺序选取每条边,如果这条边的两个端点不属于同一集合,那么就将它们合并,直到所有的点都属于同一个集合为止。

    http://cogs.pro/cogs/problem/problem.php?pid=7

    /****************************************************************************************************
    
                                            最小生成树(Kruskal) 
                            
    
    ********************************************************************************************************/
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    struct Edge{
        int from,to,dist;
        bool operator <(const Edge a)const{
            return dist<a.dist;
        }
    }a[1200000];
    int mFind[1550];
    int Find(int x){//并查集 
        if(mFind[x]==x)return x;
        else mFind[x]=Find(mFind[x]);
        return mFind[x];
    }
    int main(){
        freopen("mcst.in","r",stdin);
        freopen("mcst.out","w",stdout);
        int n,x,a1=0;scanf("%d",&n);
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                scanf("%d",&x);
                if(x!=-1&&i<j)a[a1].from=i,a[a1].to=j,a[a1++].dist=x;
            }
        }
        for(int i=0;i<n;i++)mFind[i]=i;
        sort(a,a+a1);int j=0; //将所有边排序 
        int fa,fb,u,v,ans=0;
        for(int i=1;i<n;i++){//将连接两部分的最短边加入生成树 
            while(1){
                u=a[j].from,v=a[j].to;
                fa=Find(u),fb=Find(v);
                if(fa!=fb){
                    ans+=a[j++].dist,mFind[fa]=fb;
                    break;
                }
                j++;
            }
        }
        printf("%d",ans);
        return 0;
    }

     prim算法

    其从一个顶点出发,选择这个顶点发出的边中权重最小的一条加入最小生成树中,然后又从当前的树中的所有顶点发出的边中选出权重最小的一条加入树中,以此类推,直到所有顶点都在树中,算法结束。

    http://cogs.pro/cogs/problem/problem.php?pid=185

    /****************************************************************************************************
    
                                            最小生成树(Prim)堆优化 
                            
    
    ********************************************************************************************************/
    #include<cstdio>
    #include<algorithm>
    #include<queue> 
    using namespace std;
    struct Edge{
        int next,to,dist;
        bool operator <(const Edge a)const{
            return dist>a.dist;
        }
    }a[100000],s;
    priority_queue<Edge> t;
    bool b[305];
    int f[305],top=0;
    inline void add_edge(int from,int to,int dis){
        a[++top].next=f[from],a[top].dist=dis,a[top].to=to;f[from]=top;
    }
    int main(){
        freopen("water.in","r",stdin);
        freopen("water.out","w",stdout);
        int n,x;
        scanf("%d",&n);
        for(int i=0;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&x);
                add_edge(i,j,x);
            }
        }
        int ans=0,v=0;b[0]=1;
        for(int i=0;i<n;i++){
            int to=f[v],u;
            while(to){
                u=a[to].to;
                if(!b[u]){
                    t.push(a[to]);//如果边的终点不在生成树中,将边加入优先队列 
                }
                to=a[to].next;
            }
            s=t.top();t.pop();
            u=s.to;
            while(b[u]){//找出终点不在生成树中权值最小的边 
                s=t.top();t.pop();u=s.to;
            }
            b[u]=1;v=u;ans+=s.dist;
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    postfix 邮件中继配置
    shell脚本网络流量实时查看
    zabbix配置邮件报警(第四篇)
    pptp服务故障
    Centos6.7 ELK日志系统部署
    rrdtool 实践
    Centos6.7安装Cacti教程
    Nagios事件机制实践
    Nrpe 插件安装教程
    如何查找一个命令由哪个rpm安装&&rpm 的相关查询方法
  • 原文地址:https://www.cnblogs.com/bennettz/p/6863767.html
Copyright © 2020-2023  润新知