Kruskal算法(最小生成树)

匿名 (未验证) 提交于 2019-12-02 23:05:13

Kruskal算法:首先按照边的权值进行从小到大排序,每次从剩余的边中选择权值最小的边且不会产生回路的边加入到生成树中,直到加入n-1条边就结束;

算法难点在与如何判断是否会产生回路。这个可以通过并查集实现,将所有加入生成树的结点加入同一个集合;

代码:

#include <string.h> #include<iostream> #include<vector> #include<queue> #include <algorithm> using namespace std; struct edge{//边的结构     int u;     int v;     int w; }e[100]; int f[100];//并查集数组 bool compare(struct edge a,struct edge b){//sort函数的比较器,实现边权从小到达排序     return a.w<=b.w; } int getF(int x){//查找结点的根     if(f[x]==x) return x;     else {         f[x]=getF(f[x]);//直接连接到根结点,实现路径压缩         return f[x];     } } bool unity(int a,int b){//联合所有加入生成树的结点     int f1=getF(a);     int f2=getF(b);     if(f1!=f2){         f[f1]=f2;         return true;     }     return false; }  int main() {     int n,m;     cin>>n>>m;     for(int i=0;i<m;i++){//输入边信息         cin>>e[i].u>>e[i].v>>e[i].w;     }     for(int i=0;i<100;i++){//初始化并查集         f[i]=i;     }     sort(e,e+m,compare);//排序     int munber=0,sum=0;     for(int i=0;i<m;i++){//从小到大检测每一个结点是否可以加入生成树         if(unity(e[i].u,e[i].v)){             munber++;             sum+=e[i].w;         }         if(munber==n-1) break;//当加入n-1条边,就可以结束     }     cout<<sum<<endl;     return 0; }

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!