Prim算法和Kruskal算法
以数据结构算法 7-11 进行解释
现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式:
输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N编号。
输出格式:
输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。
输入样例:
6 15
1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
2 3 4
2 4 6
2 5 2
2 6 6
3 4 6
3 5 1
3 6 1
4 5 10
4 6 8
5 6 3
输出样例:
12
这题采用Prim算法或者Kruskal算法,但是Kruskal算法需要进行写一个并查集进行判断连通性,所以选择Prim算法进行写。
Prim算法
#include <iostream>
#include <queue>
#include <vector>
#define INF 999999
using namespace std;
int N, M, a, b, c;
int e[1010][1010] = {0}, dist[1010], vis[1010] = {0};
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
int main() {
scanf("%d%d", &N, &M);
while(M--) {
scanf("%d%d%d", &a, &b, &c);
e[a][b] = e[b][a] = c;
}
fill(dist, dist + 1010, INF);
dist[1] = 0;
q.push({0, 1});
while(q.size()) {
int u = q.top().second;
q.pop();
if(vis[u]) continue;
vis[u] = 1;
for(int v = 1; v <= N; v++) {
if(!vis[v] && e[u][v] && dist[v] > e[u][v]) {
dist[v] = e[u][v];
q.push({dist[v], v});
}
}
}
int sum = 0, conn = 1;
for(int i = 1; i <= N; i++) {
sum += dist[i];
if(!vis[i]) conn = 0;
}
if(!conn) printf("-1\n");
else printf("%d\n", sum);
return 0;
}
Kruskal算法(这边未加入并查集判断连通性)
#include <iostream>
#include <queue>
#include <vector>
#define INF 999999
using namespace std;
int N, M, a, b, c;
int vis[1010] = {0};
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
int main() {
scanf("%d%d", &N, &M);
while(M--) {
scanf("%d%d%d", &a, &b, &c);
q.push({c, a * 10000 + b});
}
int sum = 0, conn = 1;
while(q.size()) {
int m = q.top().second / 10000;
int n = q.top().second % 10000;
if(!vis[m] || !vis[n]) {
sum += q.top().first;
vis[m] = vis[n] = 1;
}
q.pop();
}
printf("%d\n", sum);
return 0;
}