学习kruskal(最小生成树)笔记

本文详细介绍了使用Kruskal算法求解最小生成树的过程。包括输入处理、边的快速排序、并查集的构建及应用等关键步骤。适用于理解图论中最小生成树的基本原理。

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

先上比葫芦画瓢的代码
#include<iostream>
using namespace std;

struct edge 
{
	int u;
	int v;
	int w;
}e[1001];

int sum = 0;
int all = 0;
int n,m;
int f[9]={0};

void quicksort(int left,int right)
{
	int i,j;
	struct edge t;
	if(left > right)
	{
		return ;
	}
	i=left;
	j=right;
	while(i != j)
	{
		//从右边开始找
		while(e[j].w>=e[left].w && i<j)
		{
			j--;
		}
		//从左面开始 
		while(e[i].w <= e[left].w && i<j)
		{
			i++;
		}
		
		//交换
		if(i<j)
		{
			t=e[i];
			e[i]=e[j];
			e[j]=t;
		} 
}
	
	//最终将基准数归位,将left和i交换
	t=e[left];
	e[left]=e[i];
	e[i]=t;
	
	quicksort(left,i-1);//处理左边 
	quicksort(i+1,right);//处理右边 
	return ; 
} 

int find(int v)
{
	if(f[v] == v)
	{
		return v;
	}
	else
	{
		f[v]=find(f[v]);
		return f[v];
	}
	
}

void  join( int v,int u)
{
	int t1,t2;
	t1=find(v);
	t2=find(u);
	if(t1 != t2)
	{
		f[t2]=t1;	
		
	}

}

int main()
{
	cin>>n>>m;
	
	for(int i=1;i<=m;i++)
	{
		cin>>e[i].u;
		cin>>e[i].v;
		cin>>e[i].w;
	}
	
	
	quicksort(1,m);
	
	
	for(int i=1;i<=n;i++)
	{
		f[i] = i;
	}
	
	
	for(int i=1;i<=m;i++)
	{
		int fa = find(e[i].u);
		int fb = find(e[i].v);
		if(fa == fb) continue;
		join(e[i].u,e[i].v);
			all ++;
		sum += e[i].w;
		cout << i << endl; 
		if(all == n-1)
		{
			break;
		}
	}
	cout<<all<<endl;
	cout<<sum<<endl;
	
	return 0;
} 

kruskal是以边为判断基准,节点是用来判断该边是否具有作为树的一部分的价值。

1,输入之类的就不说了,n个顶点,m条边。用结构体来实现,储存边的长度,两边顶点的要求。

2,对所有的边长度进行排序。

3,将没有包含在树中的顶点利用最短边引入树

4,不断重复3步。由于只引入未联通的顶点,所以当引入n-1次的话,所有的点就联通了。


关于引入部分的注意

1     引入的关键是判断是不是已经联通的顶点。

        对于所有边按升序遍历,判断该边的两个顶点是否通过其他途径已经联通。

        我所学的方法是利用并查集查找祖节点来实现的。

2     判断该节点已经在树中的话,该边遍历过不作处理。

3     该边两个节点没有通过其他途径连接的话,就将该边变为树的一部分,并将两个节点变为同一个祖先。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值