給定 M 個村莊(節點)和 N 條可能建設的道路(邊),每條道路有建設成本。要求選擇若干條道路使所有村莊連通,且總成本最小。若無法連通所有村莊,輸出 "?"。
這是標準的最小生成樹(MST)問題。村莊數 M < 100,邊數 N 可達數千,適合使用 Kruskal 算法或 Prim 算法。
int parent[MAXM];
int find(int x) {
return parent[x] == x ? x : parent[x] = find(parent[x]);
}
void unite(int x, int y) {
x = find(x); y = find(y);
if (x != y) parent[x] = y;
}
struct Edge { int u, v, w; } edges[MAXN];
bool cmp(Edge a, Edge b) { return a.w < b.w; }
int main() {
while (scanf("%d%d", &N, &M), N) {
for (int i = 0; i < N; ++i)
scanf("%d%d%d", &edges[i].u, &edges[i].v, &edges[i].w);
sort(edges, edges + N, cmp);
for (int i = 1; i <= M; ++i) parent[i] = i;
int ans = 0, cnt = 0;
for (int i = 0; i < N && cnt < M - 1; ++i) {
if (find(edges[i].u) != find(edges[i].v)) {
unite(edges[i].u, edges[i].v);
ans += edges[i].w;
++cnt;
}
}
if (cnt == M - 1) printf("%d\n", ans);
else puts("?");
}
return 0;
}