NewCodeTemplate

This commit is contained in:
e2hang
2025-12-16 20:36:27 +08:00
parent 684e35b210
commit 8253f2dcbc
26 changed files with 2547 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
#include <bits/stdc++.h>
using namespace std;
/*
通用模板:虚拟源点 + Kruskal 求最小生成树
适用场景:
- 每个节点有一个直接购买成本 cost[i]
- 节点之间有全图/部分图的额外边权 w(i,j)
- 最小代价获得所有节点(最小购买成本/最小连通代价)
思想:
- 新建虚拟节点 0
- 向所有节点 i 添加边 (0, i) 权重 cost[i]
- 将所有边 (i, j) 加入
- 对整个图做 MST
*/
struct Edge {
int u, v, w;
bool operator < (const Edge &other) const {
return w < other.w;
}
};
// -------------- DSU并查集模板 --------------
vector<int> parent;
int find(int x) {
return parent[x] == x ? x : parent[x] = find(parent[x]);
}
bool mergeSet(int x, int y) {
x = find(x);
y = find(y);
if (x == y) return false;
parent[x] = y;
return true;
}
// ----------------------------------------------
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N; // 节点数量
cin >> N;
vector<int> cost(N+1); // 每个节点的购买代价,自定义题目可按需求调整
for (int i = 1; i <= N; i++)
cin >> cost[i];
vector<Edge> edges;
// 初始化 DSU节点范围为 0 ~ NN+1 个节点)
parent.resize(N + 1);
for (int i = 0; i <= N; i++) parent[i] = i;
// Step 1添加虚拟源点 0 的边
// 边 (0, i) 表示“直接购买第 i 个节点”
for (int i = 1; i <= N; i++) {
edges.push_back({0, i, cost[i]});
}
// Step 2添加原有图的边
// 例如读取 M 条边 (u, v, w)
int M;
cin >> M;
for (int i = 0; i < M; i++) {
int u, v, w;
cin >> u >> v >> w;
edges.push_back({u, v, w});
}
// Step 3Kruskal MST
sort(edges.begin(), edges.end());
long long result = 0;
int used = 0; // 已加入的边数量
for (auto &e : edges) {
if (mergeSet(e.u, e.v)) {
result += e.w;
used++;
if (used == N) break; // N+1 个节点选 N 条边即可
}
}
cout << result << "\n";
return 0;
}