• P1546 最短网络 Agri-Net题解(克鲁斯卡尔)


    P1546 最短网络 Agri-Net

     那么这个题是一道最小生成树的板子题

    在此讲解kruskal克鲁斯卡尔方法;

    原理:

    并查集在这里被用到;

    众所周知:树满足这样一个定理:如果 图 中有n个节点并且相联通,那么找出n-1条连接所有节点的边并且使连接成的图中没有环(走一圈又回到原先节点的路径),那么这个图一定是一棵树。

    那么,我们写代码时只要满足以上条件并且使得找到的n-1条边总和最小,那么这棵树就是最小生成树啦!QWQ。

    那么,我们将每个点都看成一个集合,每个集合的初始值为这个点的编号,保证每个集合的值都不相同,从邻接矩阵(原谅本超级蒟蒻不会链式前向星)中用二重循环找出权值最小的边,将这条边连接的两个点所在的集合搞成一个集合(并查集操作),将集合的统一数值设为第一个点(始点)的集合的值,即将这两个集合加入生成树中,再用判断这两个点的集合的值是不是相同(是不是一个环)来决定是否加入树就行了。。

    (放松一下手指。)

    最后在双重循环中加入最外层循环int k=1;k<=n-1;k++来找n-1条边,就 AC

    安利两个英语单词:矩阵matrix,联通connected

    上代码:

    #include<cstdio>//matrix为矩阵 
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int n,matrix[81][81],connect[81],i0,j0,sum=0,t;//matrix为输入的数字矩阵,connect为每个点所属的连通图,sum为最小边权值之和
    int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&matrix[i][j]);//以上4行为输入操作 for(int i=1;i<=n;i++) connect[i]=i;//连通图初始化 for(int k=1;k<n;k++)//n-1条边 { int minn=2147000000;//倒也可以是2147483647 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(matrix[i][j]&&connect[i]!=connect[j]&&matrix[i][j]<minn) { minn=matrix[i][j]; i0=i;j0=j;//存下这个边的始点和终点 } sum+=minn;//加入权值之和 t=connect[j0]; for(int i=1;i<=n;i++) if(connect[i]==t)connect[i]=connect[i0];//找到集合中的元素(因为不止有一个所以for),将第二个集合合并到第一个中成为一个大的 } printf("%d",sum);//输出最小权值之和(题目中为最小费用) return 0; }

     我这个不是标准的并查集查找方式,标准的请详见我的博客https://www.cnblogs.com/lbssxz/p/10753073.html

    完。。结。。QAQ

  • 相关阅读:
    K3Cloud 解决方案版本号问题
    K3Cloud 通过元数据查询单据信息
    K3Cloud 设置分录的字段颜色
    K3Cloud 干预标准产品插件
    K3Cloud 根据单据ID 获取单据视图和数据包
    K3Cloud 后台修改账户密码策略
    K3Cloud 选择基础资料允许显示未审核数据
    K3Cloud 根据内码和基础资料元数据获取基础资料数据包
    按照应用场景划分安全测试
    常见业务场景的安全测试及安全开发
  • 原文地址:https://www.cnblogs.com/lbssxz/p/10752568.html
Copyright © 2020-2023  润新知