c++最小生成树代码

  • 边数和顶点个数上限分别为M和N,注意开辟的数组里面有的大小是M,有的大小是N
#define M 200000  //有几个0就是10的几次方
#define N 100000
  • 结构体: 边edge、顶点node(node用于并查集)
  • 全局数组:边集e,大小是边数上限、点集v,大小是顶点数上限
  • 并查集中,顶点的root为true时该顶点是根节点;当顶点是根节点时,parent等于整棵树的元素个数,否则是该顶点的父节点序号值;初始化的点集中,每个顶点都是单独的一个根节点
struct edge
{
	int x, y, w;
	bool operator <(edge e)
	{
		return w < e.w;
	}
};
edge e[M + 5];

struct node
{
	int parent;
	bool root;
	node()
	{
		parent = 1;
		root = true;
	}
};
node v[N + 5];
  • 并查集操作:查找根节点 find 和合并 unite
  • 合并时,要将元素少的树并到元素多的树上,如果是随便合并,则数据多的时候可能会超时
int find(int a)
{
	while(v[a].root != true)
		a = v[a].parent;
	return a;
}

void unite(int a, int b)
{
	if(v[a].parent > v[b].parent)  //将元素少的树并到元素多的树上
	{
		v[b].root = false;
		v[a].parent += v[b].parent;
		v[b].parent = a;
	}
	else
	{
		v[a].root = false;
		v[b].parent += v[a].parent;
		v[a].parent = b;
	}
}
  • 主函数,Kruskal算法
int main()
{
	int n, m;
	sort(e, e + m);
	int cnt = 0;
	for(int i = 0; i < m; ++i)
	{
		int u = find(e[i].x);
		int v = find(e[i].y);
		if(u != v)
		{
			++cnt;
			unite(u, v);
			//选中了e[i]这条边
			
			if(cnt == n - 1) break;
		}
	}
	if(cnt < n - 1) ;   //不连通
	else ;              //连通
	return 0;
}
  • 求从a到b的一条路径,使得路径上最大边的权值最小
    可以进行最小生成树计算,每次加入一条边之后判断ab是否连通 find(a) == find(b)
    如果连通,刚才加的边就是满足条件的边
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值