Kruskal算法 (克鲁斯卡尔)

Posted vividbingo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kruskal算法 (克鲁斯卡尔)相关的知识,希望对你有一定的参考价值。

定义

Kruskal算法是一种用来查找最小生成树的算法。

准备

树:如果一个无向连通图中不存在回路,则这种图称为树。

生成树 :无向连通图G的一个子图如果是一颗包含G的所有顶点的树,则该子图称为G的生成树。

生成树是连通图的极小连通子图。这里所谓极小是指:若在树中任意增加一条边,则将出现一条回路;若去掉一条边,将会使之变成非连通图。

最小生成树:对无向连通图的生成树,各边的权值总和称为生成树的权,权最小的生成树称为最小生成树。

构成生成树的准则有三条:

① 必须只使用该网络中的边来构造最小生成树。

② 必须使用且仅使用n-1条边来连接网络中的n个顶点

③ 不能使用产生回路的边。

实现

  ①  将原图中每条边的权值进行从小到大排序。

  ②  从小到大依次判断每条边。

       若当前边不会与当前的最小生成树形成回路,则将当前边加入当前的最小生成树。

       反之,则放弃该边,继续判断下一条边。

       直到选择了(顶点数-1)条边为止,此时的生成树为最小生成树。(一般利用并查集判断是否形成回路)

 

技术图片

 

   ① 排序 

 

技术图片

 

   ②从小到大判断每条边。

  

技术图片

代码

#include<bits/stdc++.h>
using namespace std;
struct node

 int u,v,w;
 node()
 node(int a,int b,int c) u=a;v=b;w=c;
 bool operator <(const node &n) const
 return w<n.w;
;
int f[1000];
vector<node> edge;
int find(int p)
return f[p]==-1?p:f[p]=find(f[p]);
int main()

  fill(f,f+1000,-1);
  int u,v,w,i,x,y,sum=0,cnt=0,n;
  scanf("%d",&n);
  for(i=0;i<n;i++)
  
    scanf("%d%d%d",&u,&v,&w);
    edge.push_back(node(u,v,w));
  
  sort(edge.begin(),edge.end());
  for(i=0;i<edge.size();i++)
  
      x=find(edge[i].u);
      y=find(edge[i].v);
      if(x!=y)
      
         f[y]=x;
         sum+=edge[i].w;
         printf("%d %d %d\\n",edge[i].u,edge[i].v,edge[i].w);
         if(++cnt==n-1) break;
      
    
  printf("最小生成树权值为%d",sum);
  system("pause");
  return 0;

 

以上是关于Kruskal算法 (克鲁斯卡尔)的主要内容,如果未能解决你的问题,请参考以下文章

克鲁斯卡尔算法(Kruskal算法)(最小生成树算法)-贪心

克鲁斯卡尔算法(Kruskal算法)(最小生成树算法)-贪心

(王道408考研数据结构)第六章图-第四节2:最小生成树之克鲁斯卡尔算法(思想代码演示答题规范)

克鲁斯卡尔算法

JS实现最小生成树之克鲁斯卡尔(Kruskal)算法

Kruskal算法 (克鲁斯卡尔)