最小生成树之Kruskal算法C语言

本文详细介绍了Kruskal算法的基本思路及其实现过程,通过具体的代码示例,展示了如何使用该算法来寻找图的最小生成树。算法的核心在于每次选择不会形成回路的最小权重边,并将这些边加入到生成树中,直至生成树包含所有顶点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 基本思路
    每次都找到不会构成回路的最小边,把这条边的结点收录
  • 举例
如下图:
找到最小边1,把v1,v4收录
找到最小边1,把v6,v7收录
找到最小边2,把v2收录
找到最小边2,把v3收录
找到最小边4,
找到最小边6,把v5收录

在这里插入图片描述

  • 代码
#include <iostream>
#define MAX 11111
#define SIZE 10
int root[SIZE];//存储各个结点的根结点,用来判断是否有回路 
int check(int i,int j)//检查是否有回路 
{
	int root1,root2;//分别存储i,j结点的根结点 
	while(1)
	{
		if(root[i]<0)
		{
			root1=i;
			break;
		}	
		else{
			i=root[i];
		}
	}
	while(1)
	{
		if(root[j]<0)
		{
			root2=j;
			break;
		}	
		else{
			j=root[j];
		}
	}
	if(root1==root2)//说明有回路 
	{
		return 0;
	}
	else
	{
		if(root[root1]<root[root2])//集合1比集合2大,集合2并入集合1 
		{
			root[root1]+=root[root2];
			root[root2]=root1;
		}
		else//集合2比集合1大,集合1并入集合2 
		{
			root[root2]+=root[root1];
			root[root1]=root2;
		}
		return 1;
	}
}
void Kruskal(int edge[][SIZE],int n)
{
	int count=0;
	int v1,v2;
	int tree[n][n]={0};
	while(count<n)
	{
		int min=MAX;
		v1=v2=-1;
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				if(edge[i][j]<min)
				{
					min=edge[i][j];
					v1=i;
					v2=j;
				}
			}
		}
		
		if(v1==-1 || v2==-1)
		{
			for(int i=0;i<n;i++)
			{
				for(int j=0;j<n;j++)
				{
					printf("%d ",tree[i][j]);
				}
				printf("\n");
			}
			break;
		}
		edge[v1][v2]=edge[v2][v1]=MAX;	
		if(check(v1,v2))
		{
			count++;
			tree[v1][v2]=tree[v2][v1]=min;
			
			
		}
	}
	
}
int main(int argc, char** argv) {
	int n,m;
	scanf("%d %d",&n,&m);
	int start,end,value;
	int edge[SIZE][SIZE];
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			
			edge[i][j]=MAX;
		}
		root[i]=-1;
	}
	for(int i=0;i<m;i++)
	{
		scanf("%d %d %d",&start,&end,&value);
		edge[start][end]=edge[end][start]=value;
	}
	Kruskal(edge,n);
	return 0;
}
/*
7 12
0 1 2
0 2 4
2 5 5
5 6 1
6 4 6
4 1 10
3 0 1
3 1 3
3 4 7
3 6 4
3 5 8
3 2 2
*/
  • 运行结果
    在这里插入图片描述
    结果代表的是新生成的最小生成树的边的情况
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值