最小生成树:
1.prim算法:(点集A:最小生成树的点;点集B:最小生成树外的点;每次寻找树中到树外的点,将树外的点加入树中)
2.kruskal算法:(将所有边集按升序排序;每次寻找不形成回路的边)
例题:公路村村通 (15 分)(选自PTA)
现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式:
输入数据包括城镇数目正整数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算法实现:
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define inf 0x3f3f3f3f
const int N = 1010;
struct Edge {
int v, w;
Edge(int _v, int _w) : v(_v), w(_w) {}
bool operator<(const Edge& edge)const {
return w > edge.w;
}
};
vector<Edge>E[N];
priority_queue<Edge>pq;
int dis[N], vis[N];
int prim(int n) {
memset(dis, inf, sizeof(dis));
memset(vis, 0, sizeof(vis));
Edge t(1, 0); pq.push(t);
int ans = 0, used = 0;
while (!pq.empty() && used < n) {
do {
t = pq.top(); pq.pop();
} while (!pq.empty() && vis[t.v]);
if (!vis[t.v]) {
vis[t.v] = 1;
ans += t.w;
used++;
for (int i = 0; i < E[t.v].size(); i++) {
int vv = E[t.v][i].v;
if (!vis[vv]) {
int ww = E[t.v][i].w;
if (dis[vv] > ww) {
dis[vv] = ww;
pq.push({vv, ww});
}
}
}
}
}
if (used < n) {
return -1;
}
return ans;
}
int main(int argc, char** argv) {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++) {
int v1, v2, ww;
cin >> v1 >> v2 >> ww;
E[v1].push_back({v2, ww});
E[v2].push_back({v1, ww});
}
cout << prim(n) << endl;
return 0;
}
kruskal算法实现:
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const int N = 1010;
struct Edge {
int v, to, w;
Edge() {}
Edge(int _v, int _to, int _w) : v(_v), to(_to), w(_w) {}
bool operator<(const Edge& edge)const {
return w < edge.w;
}
};
vector<Edge>E;
int fa[N];
int Find(int x) {
return fa[x] == x ? x : fa[x] = Find(fa[x]);
}
int Union(int a, int b) {
a = Find(a); b = Find(b);
fa[a] = b;
return a != b;
}
int main(int argc, char** argv) {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
fa[i] = i;
}
for (int i = 0; i < m; i++) {
int v1, v2, ww;
cin >> v1 >> v2 >> ww;
E.push_back({v1, v2, ww});
}
sort(E.begin(), E.end());
int ans = 0, used = 0;
for (int i = 0; i < m; i++) {
if (Union(E[i].v, E[i].to)) {
ans += E[i].w;
used++;
}
}
if (used == n - 1) {
cout << ans << endl;
}
else {
cout << "-1" << endl;
}
return 0;
}