Krustral 算法

简而言之,克鲁斯卡尔算法的核心又三个

1.并查集对目标的合并和查询

2.将边按权排序

3.将排序的边从小到大找未被合并到生成树中并对值进行累加


举例

(以下程序的快速排序算法个人手打,也可以借用algorithm的sort库函数进行实现)


#include"iostream"
#include"cstdio"
#include"cstdlib"
using namespace std;


struct node
{
int x;
int y;
int len;
};


typedef struct node edge;


edge e[100];


int n,m;
int t1,t2,t3;
int sum=0;
int count=0;
int biannum;
int fa[100];
int deep[100];

//一直到快排之前均为并查集的模板函数
void init(int n)
{
for(int i=1;i<=n;i++)
{
fa[i]=i;
deep[i]=0;
}
}


int find(int x)
{
if(x==fa[x])
{
return x;

else
{
return fa[x]=find(fa[x]);
}
}


void unit(int x,int y)
{
x=find(x);
y=find(y);
if(x==y);
else
{
if(deep[x]<deep[y])
{
fa[x]=y;
}
else
{
if(deep[x]==deep[y])
{
deep[x]++;

fa[y]=x;
}
}
}


bool same(int x,int y)
{
return find(x)==find(y);



void quicksort(int left,int right)                              //对边进行快速排序
{
int i,j;
edge t,temp;
if(left>right)
{
return ;
}
else
{
i=left;
j=right;
temp=e[left];
while(i!=j)
{
while(i<j&&e[j].len>=temp.len)
{
j--;
}
while(i<j&&e[i].len<=temp.len)
{
i++;
}
if(i<j)
{
t=e[i];
e[i]=e[j];
e[j]=t;
}
}
e[left]=e[i];
e[i]=temp;

quicksort(left,i-1);
quicksort(i+1,right);
return ; 
}
}


int main()
{
cin>>n>>m;
init(n);
biannum=0;
for(int i=1;i<=m;i++)
{
biannum++;
cin>>t1>>t2>>t3;                        //加入边集
e[i].x=t1;
e[i].y=t2;
e[i].len=t3;
}
quicksort(1,biannum);
for(int i=1;i<=biannum;i++)
{
if(!same(e[i].x,e[i].y))                           //判断树外一点是否在同一树上
{
unit(e[i].x,e[i].y);
count++;
sum+=e[i].len; 
}
if(count==n-1)
{
break;
}
}
cout<<sum<<endl;
return 0;




个人觉得Krustral和Prim算法在判断上的核心区别在于

Krustral利用并查集的same函数来判断一边上的两个点是否在同一棵树上,而Prim通过book数组来记录已经在生成树上的点的标号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值