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

    克鲁斯卡尔算法

    适合于求边稀疏的网的最小生成树

    思路:

    将每条边的权值按从小到大的顺序排列,然后遍历,将边放回图中,如果此时的连线不能形成环,则继续,否则将此边丢弃,直到放进去n-1条边(n个点连通需要n-1条边)结束

     

    用结构体存储顶点和边,sort排序

    struct bian//存储边的信息
    {
        int x,y,w;
    }a[maxn];

    如何判断是否成环----并查集(https:////www.cnblogs.com/subject/p/12386581.html

    如果最终父类相同说明在一个集合中(形成环)

    int getfather(int x)//递归找父类
    {
        if(father[x]==x) return x;
        father[x] = getfather(father[x]);
        return father[x];
    }
    void unionm(int x,int y)//合并
    {
        int fa,fb;
        fa = getfather(x);
        fb = getfather(y);
        if(fa!=fb) father[fa] = fb;
    }
    void Init()//父类初始化
    {
        for(int i = 1;i <= n;i++)
            father[i] = i;
        return;
    };
    
    void Kruskal()
    {
        int ans = 0;//记录权值
        int k = 0;//记录已经连几条边
        for(int i=1;i<=m;i++)
        {
            if(getfather(a[i].x)!=getfather(a[i].y))//父类不同,说明是两个集合,此边可取
            {
                unionm(a[i].x,a[i].y);//合并为一个集合
                ans+=a[i].w;//权值相加
                k++;
            }
            if(k==n-1) break;
        }
        if(k==n-1) cout<<ans<<endl;
        else cout<<"impossible"<<endl;//遍历完 也不够n-1条 说明不能形成通路。
    }

    完整代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 2e5+5;
    
    struct bian//存储边的信息
    {
        int x,y,w;
    }a[maxn];
    
    int father[maxn];//每个点的最终父类
    int n,m;
    bool cmp(const bian& a,const bian& b)
    {
        return a.w<b.w;
    }
    
    int getfather(int x)//递归找父类
    {
        if(father[x]==x) return x;
        father[x] = getfather(father[x]);
        return father[x];
    }
    void unionm(int x,int y)//合并
    {
        int fa,fb;
        fa = getfather(x);
        fb = getfather(y);
        if(fa!=fb) father[fa] = fb;
    }
    void Init()//父类初始化
    {
        for(int i = 1;i <= n;i++)
            father[i] = i;
        return;
    };
    
    void Kruskal()
    {
        int ans = 0;
        int k = 0;
        for(int i=1;i<=m;i++)
        {
            if(getfather(a[i].x)!=getfather(a[i].y))
            {
                unionm(a[i].x,a[i].y);
                ans+=a[i].w;
                k++;
            }
            if(k==n-1) break;
        }
        if(k==n-1) cout<<ans<<endl;
        else cout<<"impossible"<<endl;
    }
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>a[i].x>>a[i].y>>a[i].w;
        }
        Init();
        sort(a+1,a+1+m,cmp);
    
        Kruskal();
    
        return 0;
    }
    View Code
  • 相关阅读:
    Web API框架学习——消息管道(二)
    Web API框架学习——路由(一)
    【转】Lucene.NET详细使用与优化详解
    ASP.NET MVC 创建控制器类过程
    ASP.NET MVC创建视图过程
    ORM映射设计思想
    UWP--集合绑定数据
    UWP--MVVM简单计算器
    UWP--数据绑定的几种方式
    一个自动管理学生信息的控制台应用程序(C语言)Label:Water
  • 原文地址:https://www.cnblogs.com/subject/p/12392053.html
Copyright © 2011-2022 走看看