zoukankan      html  css  js  c++  java
  • 最小生成树Prim算法Kruskal算法

    Prim算法采用与Dijkstra、Bellamn-Ford算法一样的“蓝白点”思想;白点代表已经进入最小生成树的点,蓝点代表未进入最小生成树的点。

    算法分析 & 思想讲解:

    Prim算法每次都将一个蓝点 U 变成白点,并且此蓝点 U 与白点相连的最小边权还是当前所有蓝点中最小的。这样就相当于向生成树中添加了n-1次最小的边,最后得到的一定是最小生成树。

    我们通过对下图最小生成树的求解模拟来理解上面的思想。蓝点和虚线代表未进入最小生成树的点、边;白点和实线代表已进入最小生成树的点、边。
     
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    using namespace std;
    
    int s[1500][1500],n,distan[1500];
    bool visit[1500];
    const int maxn=0x7fffffff;
    
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
                    cin>>s[i][j];
        memset(distan,0x7f,sizeof(distan));
        distan[1]=0;
        int kk=0;
        for(int i=1;i<=n;++i)
        {    
            kk=0;
            for(int j=1;j<=n;++j)
                if(!visit[j]&&distan[j]<distan[kk])
                    kk=j;
            visit[kk]=true;
            for(int j=1;j<=n;++j)
            {
                if(!visit[j]&&s[kk][j]<distan[j])
                    distan[j]=s[kk][j];
            }
        }
        int ans=0;
        for(int i=1;i<=n;++i)
            ans+=distan[i];
        cout<<ans;
        return 0;
    }
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    using namespace std;
    
    struct node
    {
        int a,b,dis;
    }s[1500];
    
    int sum=1,n,fa[1500];
    
    bool cmp(node a,node b)
    {
        return a.dis<b.dis;
    }
    
    int find(int son)
    {
        if(fa[son]!=son)
            fa[son]=find(fa[son]);
        return fa[son];
    }
    
    int main()
    {
        int ans=0;
        cin>>n;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
                {
                    s[sum].a=i;
                    s[sum].b=j;
                    cin>>s[sum++].dis;
                }
        sort(s+1,s+sum,cmp);
        int k=0;
        for(int i=1;i<=n;++i)
        {
                int r1=find(s[i].a);
                int r2=find(s[i].b);
            if(find(s[i].a)!=find(s[i].b))
            {
                fa[r2]=r1;
                ans+=s[i].dis;
                k++;
            }
            if(k==n-1)
                break;
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    centos6.5 mysql配置整理
    第四章 Web表单
    第三章 模板
    第二章 程序的基本结构
    第一章 安装
    常见网络错误代码(转)
    微软消息队列MessageQueue(MQ)
    基于.NET平台常用的框架整理(转)
    Sqlserver更新数据表xml类型字段内容某个节点值的脚本
    正则表达式_基础知识集合
  • 原文地址:https://www.cnblogs.com/qdscwyy/p/6705142.html
Copyright © 2011-2022 走看看