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

    1、什么是最小生成树?

    我们可以知道一个有n个点n-1条边且无环的无向图一定是一棵树。

    最小生成树就是在n个节点的无向图中找到n-1条边构成一棵树且使这棵树的边权和最小。

    2、怎么求?

    1、Prim算法

    这个算法在NOI中不常用(不好用

    它的思想与Dijkstra算法相似,这里不再过多介绍

    2、Kruskal算法

    这才是我们的重点

    它的思想是先把每条边按长度从小到大排好(快排)

    然后从小到大用并查集的方法把没有"并"到一棵树上并入(在这个过程避免环的出现)

    直到加入n-1条边后停止

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std; 
    int n,m,ans;
    struct node{
        int x,y,dis;//结构体定义起点终点边权 
    }a[10001];
    int fa[10001],cnt;
    int Find(int x)
    {
        return fa[x]==x?x:fa[x]=Find(fa[x]);
    }//
    bool cmp(node a,node b)
    {
        return a.dis<b.dis;
    }
    int main()
    {
      int x,y;
      cin>>n>>m;//输入点数和边数 
      for(int i=1;i<=m;i++)
          cin>>a[i].x>>a[i].y>>a[i].dis;//输入每条边的起点终点边权 
      sort(a+1,a+m+1,cmp);//快排 
      for(int i=1;i<=n;i++)fa[i]=i;//初始化 
      for(int i=1;i<=m&&cnt<n-1;i++)
      {
          x=a[i].x;y=a[i].y;
          if(Find(x)!=Find(y))//判断是否“并”到同一棵树 
          {
              cnt++;//树的边数加一 
                ans+=a[i].dis;//累加边权 
                fa[Find(x)]=Find(y);//“并” 
          } 
      }
      if(cnt==n-1) cout<<ans; //输出 
      else cout<<"error";//不够n-1条边输出错误 
    }
  • 相关阅读:
    动态规划 01背包问题
    日常水题 蓝桥杯基础练习VIP-字符串对比
    本博客导航
    2019 ICPC 南昌 (C E G L)
    [模板]线段树
    [模板]手写双端队列(或普通队列)
    2019 ICPC Asia Yinchuan Regional (G, H)
    与超级源点与超级汇点相关的两题POJ 1062, HDU 4725
    [模板]链式向前星
    [总结]关于反向建图
  • 原文地址:https://www.cnblogs.com/zhaoxuelin/p/12659418.html
Copyright © 2011-2022 走看看