最小生成树 模板题 sdut2144(数据结构实验之图论九:最小生成树) 学习prim算法

Description
有n个城市,其中有些城市之间可以修建公路,修建不同的公路费用是不同的。现在我们想知道,最少花多少钱修公路可以将所有的城市连在一起,使在任意一城市出发,可以到达其他任意的城市。

Input
输入包含多组数据,格式如下。

第一行包括两个整数n m,代表城市个数和可以修建的公路个数。(n <= 100, m <=10000)

剩下m行每行3个非负整数a b c,代表城市a 和城市b之间可以修建一条公路,代价为c(城市编号从1到n)。

Output
每组输出占一行,仅输出最小花费。

Sample
Input

3 2
1 2 1
1 3 1
1 0

Output

2
0
#include <bits/stdc++.h>

using namespace std;

int graph[100][100], distant[100], visit[100];
int n, m;

void prim() {
	int i, j, k;
	int Min;
	int sum = 0;
	for (i = 1; i <= n; i++) {
		distant[i] = graph[1][i];				//从第一个点开始记录每一个邻边的权值
	}
	visit[1] = 1;								//记录第一个点已经进入图中,标记一下
	for (i = 2; i <= n; i++)					//从第二个点开始找
	{
		Min = 0x3f3f3f3f;						//找一个变量存下最小值
		for (j = 1; j <= n; j++)				//遍历一遍找到邻边权值最小的点
		{
			if (distant[j] < Min && visit[j] == 0)
			{
				k = j;							//用k去记录这个点
				Min = distant[j];				//用Min记录这个权值
			}
		}
		visit[k] = 1;							//找到这个点后标记一下
		sum += Min;								//sum是最后输出的所有边最小权值和,这里+=记录一下
		for (j = 1; j <= n; j++) {				//去找这个点的所有邻边(并且这个点还没有被走过)中最小的权值,更新每一个distant
			if (graph[k][j] < distant[j] && visit[j] == 0) {
				distant[j] = graph[k][j];
			}
		}
	}
	printf("%d\n", sum);
}

int main() {
	while (~scanf("%d %d", &n, &m)) {
		memset(visit, 0, sizeof(visit));
		memset(graph, 0x3f, sizeof(graph));
		memset(distant, 0x3f, sizeof(distant));
		if (m < n - 1) {
			printf("0\n");
			continue;
		}
		for (int i = 1; i <= n; i++) {
			graph[i][i] = 0;
		}
		while (m--) {
			int u, v, c;
			scanf("%d %d %d", &u, &v, &c);
			if (c < graph[u][v]) {
				graph[u][v] = graph[v][u] = c;
			}
		}
		prim();
	}
	return 0;
}

参考博客 prim算法讲解

多看几遍代码 理解好思想 很容易的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SDUT-OJ(Software Development University of Tsinghua Online Judge)是一个在线编程平台,提供给清华大学软件学院的学生和爱好者练习和解决算法问的环境,其中包括各种计算机科学目,包括数据结构、算法、图形等。对于"最小生成树"(Minimum Spanning Tree, MST)问,它是图论中的经典问,目标是从一个加权无向图中找到一棵包含所有顶点的树,使得树的所有边的权重之和最小。 在C语言中,最常见的是使用Prim算法或Kruskal算法来求解最小生成树Prim算法从一个顶点开始,逐步添加与当前生成树相连且权重最小的边,直到所有顶点都被包含;而Kruskal算法则是从小到大对所有边排序,每次选取没有形成环的新边加入到树中。 如果你想了解如何用C语言实现这些算法,这里简单概括一下: - 通常使用优先队列(堆)来存储边和它们的权重,以便快速查找最小值。 - 从任意一个顶点开始,遍历与其相邻的边,若新边不形成环,就更新树,并将新边加入优先队列。 - Kruskal算法: - 先将所有的边按照权重升序排序。 - 创建一个空的最小生成树,然后依次取出排序后的边,如果这条边连接的两个顶点不在同一个连通分量,则将其添加到树中。 如果你需要更详细的代码示例,或者有具体的问想了解(比如如何处理环、如何实现优先队列等),请告诉我,我会为你提供相应的帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值