输入格式: 第一行包含两个整数n和m,n为关系网中的人数。 编号从1至n,刘老板是第1位,校长是第n位。M表示刘老板的关系网中有M个关系。(3 <n= 30, 3<=m <=1000) 接下来有m行。每行包含三个整数A、B和C,意思是A和B之间存在关系,如果A向B或B向A求助,刘老板将支付C元。 输出格式: 在你尽了最大努力后,输出Boss Liu要花的最少的钱。如果Boss Liu不能把他的孩子送到大学,就打印“Fail”。c++数组模拟
时间: 2024-03-12 09:43:48 浏览: 113
CSP-J组复赛第二题 公路附件
这也是一个最小生成树的问题,同样可以使用Kruskal算法或Prim算法求解。以下是Kruskal算法的另一种实现,使用数组模拟并查集:
```c++
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 35, M = 1010;
struct Edge {
int u, v, w;
} edges[M];
bool cmp(const Edge& a, const Edge& b) {
return a.w < b.w;
}
int parent[N];
int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
void unite(int x, int y) {
int px = find(x), py = find(y);
if (px != py) {
parent[px] = py;
}
}
int kruskal(int n, int m) {
for (int i = 1; i <= n; i++) {
parent[i] = i;
}
sort(edges, edges + m, cmp);
int cnt = 0, ans = 0;
for (int i = 0; i < m; i++) {
int u = edges[i].u, v = edges[i].v, w = edges[i].w;
if (find(u) == find(v)) {
continue;
}
unite(u, v);
ans += w;
cnt++;
if (cnt == n - 1) {
break;
}
}
if (cnt < n - 1) {
return -1;
} else {
return ans;
}
}
int main() {
int n, m;
cin >> n >> m;
for (int i = 0; i < m; i++) {
cin >> edges[i].u >> edges[i].v >> edges[i].w;
}
int ans = kruskal(n, m);
if (ans == -1) {
cout << "Fail" << endl;
} else {
cout << ans << endl;
}
return 0;
}
```
在这个实现中,我们使用了两个数组:parent和edges。其中parent数组用于模拟并查集,edges数组用于存储所有的边。在kruskal函数中,我们首先初始化每个节点的父节点为自己,然后将所有边按权值从小到大排序。接着从小到大枚举每条边,如果它的两个端点不在同一个连通块内,则将它们合并,并将边的权值累加到答案中。最后如果生成树的边数小于n-1,则说明无法将所有节点连通,打印“Fail”,否则打印答案。
阅读全文