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算法讲解
多看几遍代码 理解好思想 很容易的