完全图的最小生成树

本文介绍了一种解决完全图最小生成树问题的方法,通过贪心算法中的Prim算法来实现。具体步骤是从图中选择一个点作为起点,然后依次添加当前未加入树的节点中与树中节点连接的边权值最小的节点,直至包含所有节点。样例和AC代码也一并给出,展示了解决此类问题的完整过程。

完全图的最小生成树

关键字: 贪心算法,图,最小生成树
题目描述:给定一个图,图中包括 n 个点,每个点 i 有一个权值A[i]。这个图是一个完全图,任意两点 i 和 j 之间有一条长度为 A[i]+A[j] 的无向边,问该图最小生成树所有边的长度和。
输入:第一个数为数据组数T, T≤50。
对于每组数据,首先输入一个数n,n≤100000。
接下来一行n个数,分别表示A[1],…,A[n],1≤A[i]≤10,000,000。
输出:对于每组数据,输出一行,最小生成树的边权和。
样例

//Input
1
4
5 6 5 9 
//Output
35

题解:由于该题中边的权值由所选取的点决定,故采用prim算法构建最小生成树。由题,该树每条边的权值为该边两端点权值和,根据prim算法,选取当前点集 EEE 中最小元 uuu 为起始点,记其权值为A[uuu],不断选取当前剩余点集中的最小元 viv_ivi,记其权值为A[viv_ivi],则以点 uuu 为根,边 <u,vi><u,v_i><u,vi>为茎的树则为该完全图的最小生成树。不妨令最小元为A[vjv_jvj],则其所有边的长度和为
A[u]+A[v1]+⋯+A[u]+A[vj−1]+A[u]+A[vj+1]+⋯+A[u]+A[vn]=(n−2)A[u]+∑1nA[vi]A[u]+A[v_1]+\cdots+A[u]+A[v_{j-1}]+A[u]+A[v_{j+1}]+\cdots+A[u]+A[v_n] = (n-2)A[u]+\sum_1^nA[v_i]A[u]+A[v1]++A[u]+A[vj1]+A[u]+A[vj+1]++A[u]+A[vn]=(n2)A[u]+1nA[vi]

AC代码 (C++ 代码长度-515Bytes 运行时长-516ms 运行内存-3304KB)
#include <iostream>
#include <cstdio>
using namespace std;

int n;
void MiniSpTree ();
int main () {
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	int T, t = 1;
	cin >> T;
	while (t <= T) {
		cin >> n;
		MiniSpTree ();
		++t;
	}
	
	return 0;
}

void MiniSpTree () {
	int min = 0x3f3f3f3f;
	long long res = 0;
	
	for (int i = 0; i < n; ++i) {
		int temp;
		cin >> temp;
		res += temp;
		if (min > temp)
			min = temp;
	}
	res += (n-2)*min;
	cout << res << endl;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值