[kuangbin带你飞]专题六 做题顺序与题解 【最小生成树】

随便说点:

博主正在刷kuangbin专题的题目,初学者,没接触过什么算法,刷题的初衷是备战蓝桥杯,后来发现了算法资料大多是针对acm的,挑选kuangbin专题入门也是如此,毕竟这样分类看起来比较有目的的刷题。
所以有的代码比较冗余,越往后面的题解代码变化越大,
代码的风格和算法思想也是在一步步的学习和进步,多多包容,互相借鉴。

建议做题顺序:
做最小生成树专题没最短路和并查集专题时那么吃力,题目难度有下降。所以把题解都整合在一篇博客里

最小生成树基础:1 2 4 5 6 9 12 14
最小生成树应用:10 3 8 7
这是我做完一遍之后觉得比较好的做题顺序,由易到难,相同类型题放在一起加深理解。

1.POJ 1251 Jungle Roads

把字符转化成整型,然后套用模板

//poj1251
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 28, INF = 0x3f3f3f3f;
int maps[N][N],visit[N];
int d[N];
int n;
int prim()
{
   
   
	int ans = 0;
	for (int i = 1; i < n; i++)
		d[i] = maps[0][i];
	d[0] = 0;
	for (int i = 1; i < n; i++)
	{
   
   
		int t = -1;
		for (int j = 1; j < n; j++)
		{
   
   
			if (!visit[j])
				if (d[j] < d[t] || t == -1)
					t = j;
		}
		visit[t] = 1;
		ans += d[t];
		for (int j = 1; j < n; j++)
			if (!visit[j])
				d[j] = min(d[j], maps[t][j]);
	}
	return ans;
}
int main()
{
   
   
	while (~scanf("%d", &n),n)
	{
   
   
		memset(maps, 0x3f, sizeof(maps));
		memset(visit, 0, sizeof(visit));
		for (int i = 0; i < n-1; i++)
		{
   
   
			char u;
			int t;
			scanf(" %c %d", &u, &t);
			while (t--)
			{
   
   
				char v;
				int w;
				scanf(" %c %d", &v,&w);
				maps[i][v - 'A'] = w;
				maps[v - 'A'][i] = w;
			}
		}
		printf("%d\n", prim());
	}
	return 0;
}

2.POJ 1287 Networking

模板题

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 55, INF = 0x3f3f3f3f;
int maps[N][N],visit[N];
int d[N];
int n, m;
int prim()
{
   
   
	int ans = 0;
	for (int i = 2; i <= n; i++)
		d[i] = maps[1][i];
	d[1] = 0;
	for (int i = 2; i <= n; i++)
	{
   
   
		int t = -1;
		for (int j = 2; j <= n; j++)
		{
   
   
			if (!visit[j])
				if (d[j] < d[t] || t == -1)
					t = j;
		}
		visit[t] = 1;
		ans += d[t];
		for (int j = 2; j <= n; j++)
			if (!visit[j])
				d[j] = min(d[j], maps[t][j]);
	}
	return ans;
}
int main()
{
   
   
	while (~scanf("%d%d", &n, &m), n)
	{
   
   
		memset(maps, 0x3f, sizeof(maps));
		memset(visit, 0, sizeof(visit));
		for (int i = 0; i < m; i++)
		{
   
   
			int u, v, w;
			scanf("%d%d%d", &u, &v, &w);
			if (w < maps[u][v]) {
   
   
				maps[u][v] = w;
				maps[v][u] = w;
			}
		}
		printf("%d\n", prim());
	}
	return 0;
}

3.POJ 2031 Building a Space Station

prim,注意 若两圆心距离-半径之和< =0则两点权值设置为0

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 105;
const double INF = 1e15;
int visit[N];
double d[N];
int n,m;
struct node {
   
   
	double  x, y, z, r;
}maps[N];
double getDis(double x1, double y1,double z1, double x2, double y2, double z2 )
{
   
   
	return sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)+ (z1 - z2)*(z1 - z2));
}
double prim()
{
   
   
	memset(visit, 0, sizeof(visit));
	for (int i = 1; i <= n; i++)
		d[i] = INF;
	double ans = 0;
	for (int i = 2; i <= n; i++) {
   
   
		double len = getDis(maps[1].x, maps[1].y, maps[1].z, maps[i].x, maps[i].y, maps[i].z);
		double r = maps[1].r+ maps[i].r;
		if (r >= len)	d[i] = 0;
		else d[i] = len-r;
			
	}	
	d[1] = 0;
	for (int i = 2; i <= n; i++)
	{
   
   
		int t = -1;
		for (int j = 2; j <= n; j++)
		{
   
   
			if (!visit[j])
				if (d[t] > d[j]|| t == -1)
					t = j;
		}
		visit[t] = 1;
		ans += d[t];
		for (int j = 2; j <= n; j++)
			if (!visit[j]) {
   
   
				double len = getDis(maps[t].x, maps[t].y, maps[t].z, maps[j].x, maps[j].y, maps[j].z);
				double r = maps[t].r + maps[j].r;
				if (r >= len)len = 0;
				else len = len - r;
				d[j] = min</
### 关于 kuangbin ACM 算法竞赛培训计划 #### 数论基础专题介绍 “kuangbin专题十四涵盖了数论基础知识的学习,旨在帮助参赛者掌握算法竞赛中常用的数论概念和技术。该系列不仅提供了丰富的理论讲解,还推荐了一本详细的书籍《算法竞赛中的初等数论》,这本书包含了ACM、OI以及MO所需的基础到高级的数论知识点[^1]。 #### 并查集应用实例 在另一个具体的例子中,“kuangbin”的第五个专题聚焦于并查集的应用。通过解决实际问题如病毒感染案例分析来加深理解。在这个场景下,给定一组学生及其所属的不同社团关系图,目标是从这些信息出发找出所有可能被传染的学生数目。此过程涉及到了如何高效管理和查询集合成员之间的连通性问题[^2]。 #### 搜索技巧提升指南 对于简单的搜索题目而言,在为期约两周的时间里完成了这一部分内容的学习;尽管看似容易,但对于更复杂的状况比如状态压缩或是路径重建等问题,则建议进一步加强训练以提高解题能力[^3]。 ```python def find_parent(parent, i): if parent[i] == i: return i return find_parent(parent, parent[i]) def union(parent, rank, x, y): rootX = find_parent(parent, x) rootY = find_parent(parent, y) if rootX != rootY: if rank[rootX] < rank[rootY]: parent[rootX] = rootY elif rank[rootX] > rank[rootY]: parent[rootY] = rootX else : parent[rootY] = rootX rank[rootX] += 1 # Example usage of Union-Find algorithm to solve the virus spread problem. ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值