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

    题目大意:
    求出最小生成树。


    思路:
    这道题有两种方法:
    (1)最小生成树
    (2)并查集

    最小生成树:

    数据n<=5000,简直就是dij的模版。。。

    并查集:

    以两点之间的距离从小到大排序,再利用贪心思想,如果father[i]!=father[j],那么将i的父亲指向j,再用sum加上这两点之间的距离,加上一点优化即可AC。


    代码:

    最小生成树:

    #include <cstdio>
    using namespace std;
    int a[5001][5001],n,b[5001],k,sum,minn,c[5001];
    
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
        {
            for (int j=1;j<=n;j++) 
            {
                scanf("%d",&a[i][j]);
            } 
            b[i]=i;
        } 
        for (int i=1;i<=n;i++)
         if (a[1][i]!=0) c[i]=a[1][i];  //初始化
        for (int q=1;q<=n-1;q++)
        {
            minn=2147483647;
            for (int i=1;i<=n;i++)
            {
                if (c[i]<minn&&c[i]!=0)  //求集合外的距离集合最近的点
                {
                    minn=c[i];
                    k=i;
                }
            }
            c[k]=0;
            b[k]=1;
            sum+=minn;
            for (int i=1;i<=n;i++)
             if (b[i]!=1&&c[i]>a[k][i]) c[i]=a[k][i];  //重新赋值
        }
        printf("%d\n",sum);
        return 0;
    }
    

    并查集:

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <map>
    using namespace std;
    
    int n,k,sum,m;
    map<int,int> father;
    
    struct N
    {
        int x,y,f;
    }a[2500001];
    
    int cmp(N q,N p)  
    {
        return q.f<p.f;
    }
    
    int find(int a)  //路径压缩
    {
        return a==father[a]?a:father[a]=find(father[a]);
    }
    
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
         for (int j=1;j<=n;j++)
         {
            k++;
            a[k].x=i;
            a[k].y=j;
            scanf("%d",&a[k].f);
         }   
        sort(a+1,a+1+k,cmp);  //快排
        for (int i=1;i<=k;i++)
         father[i]=i;  //并查集初始化
        int j=0;
        for (int i=1;i<k;i++)
        {
            if(find(a[i].x)==find(a[i].y)) continue;
            father[find(a[i].y)]=find(a[i].x);  //将a[i].y的父亲指向a[i].y
            sum+=a[i].f;
            if (++m==n-1) break;  //优化
        }
        printf("%d\n",sum);
        return 0;
    }
  • 相关阅读:
    程序员常用资源工具集合(建议收藏)
    程序员常用资源工具集合(建议收藏)
    16个烧光你脑细胞的悖论
    2.2_模型的选择
    2.1_Scikit-learn数据集
    Sklearn数据集与机器学习
    1.4_数据的特征选择
    1.4_特征的选择
    1.3_数据的特征预处理
    1.2_数据的特征抽取
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/9313093.html
Copyright © 2011-2022 走看看