main
黄海 2 years ago
parent acf9cb1d3d
commit ae40ca4f4d

@ -24,7 +24,7 @@ int find(int x) {
} }
// Kruskal算法 // Kruskal算法
int kruskal() { void kruskal() {
// 1、按边权由小到大排序 // 1、按边权由小到大排序
sort(edge, edge + m); sort(edge, edge + m);
// 2、并查集初始化 // 2、并查集初始化
@ -37,8 +37,7 @@ int kruskal() {
p[a] = b, res += c, cnt++; // cnt是指已经连接上边的数量 p[a] = b, res += c, cnt++; // cnt是指已经连接上边的数量
} }
// 4、特判是不是不连通 // 4、特判是不是不连通
if (cnt < n - 1) return INF; if (cnt < n - 1) res = INF;
return res;
} }
int main() { int main() {
@ -48,10 +47,10 @@ int main() {
cin >> a >> b >> c; cin >> a >> b >> c;
edge[i] = {a, b, c}; edge[i] = {a, b, c};
} }
int t = kruskal(); kruskal();
if (t == INF) if (res == INF)
puts("impossible"); puts("impossible");
else else
printf("%d\n", t); printf("%d\n", res);
return 0; return 0;
} }

@ -122,7 +122,7 @@ int find(int x) {
} }
// Kruskal算法 // Kruskal算法
int kruskal() { void kruskal() {
// 1、按边权由小到大排序 // 1、按边权由小到大排序
sort(edge, edge + m); sort(edge, edge + m);
// 2、并查集初始化 // 2、并查集初始化
@ -135,8 +135,7 @@ int kruskal() {
p[a] = b, res += c, cnt++; // cnt是指已经连接上边的数量 p[a] = b, res += c, cnt++; // cnt是指已经连接上边的数量
} }
// 4、特判是不是不连通 // 4、特判是不是不连通
if (cnt < n - 1) return INF; if (cnt < n - 1) res = INF;
return res;
} }
int main() { int main() {
@ -146,11 +145,11 @@ int main() {
cin >> a >> b >> c; cin >> a >> b >> c;
edge[i] = {a, b, c}; edge[i] = {a, b, c};
} }
int t = kruskal(); kruskal();
if (t == INF) if (res == INF)
puts("impossible"); puts("impossible");
else else
printf("%d\n", t); printf("%d\n", res);
return 0; return 0;
} }
``` ```

@ -1,44 +1,58 @@
#include <bits/stdc++.h> #include <bits/stdc++.h>
using namespace std; using namespace std;
const int N = 110, M = 210; const int N = 110, M = 210;
int n, m, fa[N]; const int INF = 0x3f3f3f3f;
//结构体 int n, m; // n条顶点,m条边
struct Edge { int res; // 最小生成树的权值和
int a, b, w; int cnt; // 最小生成树的结点数
bool operator<(const Edge &t) {
return w < t.w; // Kruskal用到的结构体
struct Node {
int a, b, c;
bool const operator<(const Node &t) const {
return c < t.c; // 边权小的在前
} }
} e[M]; } edge[M]; // 数组长度为是边数
//并查集 // 并查集
int p[N];
int find(int x) { int find(int x) {
if (fa[x] != x) fa[x] = find(fa[x]); //路径压缩 if (p[x] != x) p[x] = find(p[x]);
return fa[x]; return p[x];
}
// Kruskal算法
int kruskal() {
// 1、按边权由小到大排序
sort(edge, edge + m);
// 2、并查集初始化
for (int i = 1; i <= n; i++) p[i] = i;
// 3、迭代m次
for (int i = 0; i < m; i++) {
int a = edge[i].a, b = edge[i].b, c = edge[i].c;
a = find(a), b = find(b);
if (a != b)
p[a] = b, res += c, cnt++; // cnt是指已经连接上边的数量
}
// 4、特判是不是不连通
if (cnt < n - 1) return INF;
return res;
} }
int main() { int main() {
cin >> n >> m; cin >> n >> m;
//并查集初始化 int sum = 0;
for (int i = 1; i <= n; i++) fa[i] = i;
// Kruskal算法直接记录结构体 // Kruskal算法直接记录结构体
for (int i = 0; i < m; i++) { for (int i = 0; i < m; i++) {
int a, b, c; int a, b, c;
cin >> a >> b >> c; cin >> a >> b >> c;
e[i] = {a, b, c}; edge[i] = {a, b, c};
sum += c;
} }
sort(e, e + m); //不要忘记e数组的长度是边的数量
int res = 0; int t = kruskal();
//枚举每条边 printf("%d\n", sum - t);
for (int i = 0; i < m; i++) {
int a = find(e[i].a), b = find(e[i].b), c = e[i].w;
if (a != b)
fa[a] = b;
else
res += c; //去掉的边权
}
printf("%d\n", res);
return 0; return 0;
} }

Loading…
Cancel
Save