HDU - 1233 还是畅通工程 (Kruskal)

题目链接

题意:给出一个n和一个n*(n-1)/2条无向边,求MST

题解:prime邻接矩阵和prime邻接表也可以,这里是为了写一波完全图下较慢的Kruskal

代码如下:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int maxn = 1e3;
struct edge
{
	int u, v, w;
	edge() {}
	edge(int uu, int vv, int ww) :u(uu), v(vv), w(ww) {}
	bool operator < (const edge &a)const
	{
		return w<a.w;
	}
}e[300005];
int e_cnt;
struct unionfind
{
	int prt[maxn];  //并查集标记集合父辈
	int rank[maxn];  //用于记录集合内成员个数,保证将较小集合并入较大几何减小时间
	unionfind(int n)  //初始化
	{
		for (int i = 1; i <= n; i++)
		{
			prt[i] = i;
			rank[i] = 0;
		}
	}
	int find(int x)  //并查集查找集合父辈
	{
		if (prt[x] == x)return x;
		else return prt[x] = find(prt[x]);
	}
	bool unite(int x, int y)  //判断是否同一个集合
	{
		x = find(x);
		y = find(y);
		if (x == y)return false;
		if (rank[x]<rank[y])prt[x] = y;
		else
		{
			prt[y] = x;
			if (rank[x] == rank[y])rank[x]++;
		}
		return true;
	}
};
int kruskal(int n)
{
	unionfind u(n);  //初始化
	int cnt = 0, ans = 0;
	sort(e, e + e_cnt);
	for (int i = 0; cnt < n - 1 && i < e_cnt; i++)//最多增n-1次且最多有e_cnt条边
	{
		if (u.unite(e[i].u, e[i].v))//判断是否不在同一集合
		{
			cnt++;
			ans += e[i].w;
		}
	}
	return ans;
}
int main()
{
	int n;
	while (~scanf("%d", &n) && n)
	{
		for (int i = 0; i< n*(n - 1) / 2; i++)  //默认MST都是无向边,kruskal只用存一条即可
			scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
		e_cnt = n*(n - 1) / 2;
		printf("%d\n", kruskal(n));
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值