SCU 3366 Watering Hole

题目链接:SCU 3366 Watering Hole

题目大意:

题解:
在已有图中添加一个点,表示地下天然水源,该点与其他各点之间建立一条权值为打井费用的边,在某一点打井相当于选择该点与地下水源之间的边,然后跑最小生成树即可。

#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;

int n, fa[310], cnt;

struct Edge {
    int u, v, w;
    bool operator<(const Edge &obj) const { return w < obj.w; }
} edge[45310];

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }

int kruscal() {
    int ans = 0;
    for (int i = 0; i <= n; ++i) {
        fa[i] = i;
    }
    int tot = 0;
    for (int i = 1; i <= cnt; ++i) {
        int u = edge[i].u, v = edge[i].v;
        int fau = find(u), fav = find(v);
        if (fau != fav) {
            fa[fau] = fav;
            tot++;
            ans += edge[i].w;
            if (tot == n) {
                return ans;
            }
        }
    }
}

int main() {
    while (scanf("%d", &n) == 1) {
        cnt = 0;
        for (int i = 1; i <= n; ++i) {
            edge[++cnt].u = 0;
            edge[cnt].v = i;
            scanf("%d", &edge[cnt].w);
        }
        for (int i = 1, w; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                scanf("%d", &w);
                if (i < j) {
                    edge[++cnt].u = i;
                    edge[cnt].v = j;
                    edge[cnt].w = w;
                }
            }
        }
        sort(edge + 1, edge + cnt + 1);
        printf("%d\n", kruscal());
    }
    return 0;
}
posted @ 2022-01-30 20:31  ZZHHOOUU  阅读(35)  评论(0)    收藏  举报