parent
aa090091c7
commit
430bc71562
@ -1,45 +0,0 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
const int N = 110;
|
||||
const int M = 10010;
|
||||
|
||||
struct Node { //用结构体存储每条边
|
||||
int f, t, w;
|
||||
bool operator<(const Node &e) const {
|
||||
return w < e.w;
|
||||
}
|
||||
} edges[M];
|
||||
|
||||
int p[N];
|
||||
|
||||
int find(int x) { //并查集找根节点
|
||||
if (p[x] != x) p[x] = find(p[x]);
|
||||
return p[x];
|
||||
}
|
||||
|
||||
int n, idx, ans;
|
||||
int main() {
|
||||
scanf("%d", &n);
|
||||
|
||||
//邻接矩阵
|
||||
for (int i = 1; i <= n; i++)
|
||||
for (int j = 1; j <= n; j++) {
|
||||
int w;
|
||||
scanf("%d", &w);
|
||||
edges[idx++] = {i, j, w}; //加入当前的边
|
||||
}
|
||||
sort(edges, edges + idx); //对边权进行排序,注意这里不是优先队列,是谁小谁在前
|
||||
|
||||
for (int i = 1; i <= n; i++) p[i] = i; //并查集初始化
|
||||
for (int i = 1; i <= idx; i++) { //枚举每条边
|
||||
int f = find(edges[i].f), t = find(edges[i].t);
|
||||
if (f != t) { //当前两点不连通
|
||||
ans += edges[i].w; //更新答案
|
||||
p[f] = t; //让两点变连通
|
||||
}
|
||||
}
|
||||
printf("%d", ans);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
#include <bits/stdc++.h>
|
||||
|
||||
using namespace std;
|
||||
const int N = 510;
|
||||
const int INF = 0x3f3f3f3f;
|
||||
|
||||
int n, m;
|
||||
int g[N][N]; // 稠密图,邻接矩阵
|
||||
int dis[N]; // 这个点到集合的距离
|
||||
bool st[N]; // 是不是已经使用过
|
||||
int res; // 最小生成树里面边的长度之和
|
||||
int pre[N]; // 前驱结点
|
||||
|
||||
// 普利姆算法求最小生成树
|
||||
int prim() {
|
||||
for (int i = 0; i < n; i++) { // 迭代n次
|
||||
int t = -1;
|
||||
for (int j = 1; j <= n; j++)
|
||||
if (!st[j] && (t == -1 || dis[t] > dis[j])) t = j;
|
||||
if (i && dis[t] == INF) return INF; // 非连通图,没有最小生成树
|
||||
if (i) res += dis[t];
|
||||
for (int j = 1; j <= n; j++)
|
||||
if (!st[j] && g[t][j] < dis[j]) {
|
||||
dis[j] = g[t][j];
|
||||
pre[j] = t; // 记录是由谁转移而来
|
||||
}
|
||||
st[t] = true;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main() {
|
||||
cin >> n >> m;
|
||||
memset(g, 0x3f, sizeof g);
|
||||
memset(dis, 0x3f, sizeof dis);
|
||||
memset(pre, -1, sizeof pre); // 记录前驱路径
|
||||
|
||||
// 读入数据
|
||||
while (m--) {
|
||||
int a, b, c;
|
||||
cin >> a >> b >> c;
|
||||
g[a][b] = g[b][a] = min(g[a][b], c);
|
||||
}
|
||||
int t = prim();
|
||||
if (t == INF)
|
||||
puts("impossible");
|
||||
else
|
||||
cout << t << endl;
|
||||
|
||||
// 输出前驱结点
|
||||
for (int i = 1; i <= n; i++) printf("%d ", pre[i]);
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
|
||||
const int N = 110;
|
||||
const int M = 10010;
|
||||
|
||||
struct Node { // 用结构体存储每条边
|
||||
int f, t, w;
|
||||
bool operator<(const Node &e) const {
|
||||
return w < e.w;
|
||||
}
|
||||
} edges[M];
|
||||
|
||||
int p[N];
|
||||
|
||||
int find(int x) { // 并查集找根节点
|
||||
if (p[x] != x) p[x] = find(p[x]);
|
||||
return p[x];
|
||||
}
|
||||
|
||||
int n, idx, ans;
|
||||
int main() {
|
||||
cin >> n;
|
||||
for (int i = 1; i <= n; i++) p[i] = i; // 并查集初始化
|
||||
|
||||
// 邻接矩阵
|
||||
for (int i = 1; i <= n; i++)
|
||||
for (int j = 1; j <= n; j++) {
|
||||
int w;
|
||||
cin >> w;
|
||||
edges[idx++] = {i, j, w}; // 加入当前的边
|
||||
}
|
||||
sort(edges, edges + idx); // 对边权进行排序,谁小谁在前
|
||||
|
||||
for (int i = 1; i <= idx; i++) { // 枚举每条边
|
||||
int f = find(edges[i].f), t = find(edges[i].t);
|
||||
if (f != t) { // 当前两点不连通
|
||||
ans += edges[i].w; // 更新答案
|
||||
p[f] = t; // 让两点变连通
|
||||
}
|
||||
}
|
||||
cout << ans << endl;
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
## 最小生成树
|
||||
|
||||
$Prim$算法和$Kruskal$算法都是用于 **求解最小生成树的算法**,但它们的使用场景和应用领域存在一些差异。
|
||||
|
||||
#### $Prim$算法
|
||||
① $Prim$算法是一种贪心算法,基于顶点的方式构建最小生成树。
|
||||
② $Prim$算法 **适用于稠密图**,即边的数量接近于完全图$(n*(n-1)/2)$的图。
|
||||
③ $Prim$算法从一个起始顶点开始逐步扩展,直到生成一个包含所有顶点的最小生成树。
|
||||
④ $Prim$算法的时间复杂度为$O(ElogV)$,对于稠密图有较好的性能。
|
||||
|
||||
#### $Kruskal$算法
|
||||
① $Kruskal$算法是一种基于边的方式构建最小生成树的算法。
|
||||
② $Kruskal$算法 **适用于稀疏图**,即边的数量远小于完全图$(n*(n-1)/2)$的图。
|
||||
③ $Kruskal$算法按权值递增的顺序选择边,并通过判断是否构成环来决定是否将边加入最小生成树。
|
||||
④ $Kruskal$算法的时间复杂度为$O(ElogE)$,对于稀疏图有较好的性能。
|
||||
|
||||
#### 总结
|
||||
总体而言,$Prim$算法适用于稠密图,具有更好的时间复杂度,而$Kruskal$算法适用于稀疏图,具有相对较好的性能。在选择使用哪种算法时,可以根据图的特性和规模来进行选择。
|
Loading…
Reference in new issue