zoukankan      html  css  js  c++  java
  • kruskal算法的套路

    算法核心思想:贪心

    给定一个带权图,求连通所有节点所需的最小权和

    n个节点,需要连n-1条边,这些边的权值都是尽量小的,所以连最小生成树从边权最小的开始连

    1:将边按照权从小到大排序(或者不排序,只要能顺利的拿到权最小的那条边就行)

    2:每次选定权最小的边  连,这条边一旦导致成环就必须舍弃掉,

    3:重复处理直到连了n-1条边或者所有边都考虑过了

      判断成环与否使用并查集

    hdu1162

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e4;
    struct edge
    {
        int u,v;
        double w;
    }e[maxn];
    int pre[maxn],n,m,cnt;
    double a[maxn],b[maxn],x,y,sum;
    bool cmp(edge a, edge b){return a.w<b.w;}
    int f(int x){return x==pre[x]?x:pre[x]=f(pre[x]);}
    void kruskal()
    {
        int tot=0;
        for(int i=0;i<m&&tot<n;i++){
            int r=f(e[i].u),t=f(e[i].v);
            if(r!=t){
                tot++;pre[r]=t;sum+=e[i].w;
            }
        }
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
            cnt=0;sum=0;
            for(int i=0;i<=n;i++)pre[i]=i;
            m=n*(n-1)/2;
            for(int i=0;i<n;i++)
                scanf("%lf%lf",&a[i],&b[i]);
            for(int i=0;i<n-1;i++)
                for(int j=i+1;j<n;j++){
                    x=a[i]-a[j];y=b[i]-b[j];
                    e[cnt].u=i;e[cnt].v=j;e[cnt].w=sqrt(x*x+y*y);
                    cnt++;
                }
            sort(e,e+m,cmp);
            kruskal();
            printf("%.2f
    ",sum);
        }
        return 0;
    }
    

      

    落霞与孤鹜齐飞,秋水共长天一色
  • 相关阅读:
    Redis3.2集群部署安装
    熟悉SQL Server 数据类型
    泛型的参数简介和参数约束
    流(Stream)与文件流(FileStream)
    C#提取双引号中的字符串
    数组,一维数组,二维数组,交错数组
    结构,枚举
    C#中唯一的三元运算符
    位运算
    异常处理语句
  • 原文地址:https://www.cnblogs.com/star-and-me/p/6715467.html
Copyright © 2011-2022 走看看