/*
克鲁斯卡尔算法的核心思想是:在带权连通图中,
不断地在边集合中找到最小的边,如果该边满足
得到最小生成树的条件,就将其构造,直到最后
得到一颗最小生成树。
*/
#include<iostream>
#include<algorithm>
using namespace std;
const int MAX=1000;
int n,father[MAX],rank[MAX];
//把每条边构成一个结构体,包括起点、终点和权值
typedef struct node
{
int s;
int e;
int w;
}Edge;
Edge edge[MAX];
//把每个元素初始化为一个集合
void Make_Set()
{
for(int i=1;i<MAX;i++)
{
father[i]=i;
rank[i]=1;
}
}
//查找一个元素所在的集合,即找到其祖先
int Find_Set(int x)
{
if(x!=father[x])
father[x]=Find_Set(father[x]);
return father[x];
}
//合并x,y所在的两个集合:利用Find_Set找到其中两个
//集合的祖先,将一个集合的祖先指向另一个集合的祖先。
void Union_Set(int x,int y)
{
x=Find_Set(x);
y=Find_Set(y);
if(x==y)return ;
if(rank[x]<rank[y])
{
father[x]=Find_Set(y);
}
else
{
if(rank[x]==rank[y])
rank[x]++;
father[y]=Find_Set(x);
}
return ;
}
bool cmp(Edge o1,Edge o2)
{
return o1.w<o2.w;
}
int Kruskal(int n)//n为边的数量
{
int sum=0;
Make_Set();
for(int i=1;i<=n;i++)
{
int x=edge[i].s;
int y=edge[i].e;
if(Find_Set(x)!=Find_Set(y))
{
Union_Set(x,y);
sum+=edge[i].w;
}
}
return sum;
}
(Kruskal)克鲁斯卡尔算法
最新推荐文章于 2024-07-23 17:36:37 发布