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;
    }
  • 相关阅读:
    for循环嵌套的原理
    php for循环|求1-100之间被3整除且被5不整除的偶数
    php 1-100之间能被3整除的数字之和;
    php判断某年某月有多少天
    关系运算符
    变量
    习题5-7 使用函数求余弦函数的近似值
    习题5-6 使用函数输出水仙花数
    习题4-11 兔子繁衍问题
    习题4-9 打印菱形图案
  • 原文地址:https://www.cnblogs.com/qdscwyy/p/6705142.html
Copyright © 2011-2022 走看看