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

    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;
    }
  • 相关阅读:
    Linux下sed,awk,grep,cut,find学习笔记
    Python文件处理(1)
    KMP详解
    Java引用详解
    解决安卓中页脚被输入法顶起的问题
    解决swfupload上传控件文件名中文乱码问题 三种方法 flash及最新版本11.8.800.168
    null id in entry (don't flush the Session after an exception occurs)
    HQL中的Like查询需要注意的地方
    spring mvc controller间跳转 重定向 传参
    node to traverse cannot be null!
  • 原文地址:https://www.cnblogs.com/bennettz/p/6863767.html
Copyright © 2011-2022 走看看