【最小生成树】Constructing Roads POJ - 2421

Constructing Roads POJ - 2421

题意:

给定\(N\)个村庄,每个村庄给定\(N\)个整数,为从它出发到各个村庄(包括它自己)的距离。再给\(Q\)条信息\(x,y\),表示村庄\(x\)与村庄\(y\)之间已经有道路。问使所有村庄连通的要修的路的最短总长度。

思路:

这题应该是考察对最小生成树算法中并查集部分的理解……已有道路说明两个结点已经在计算最小生成树前合并过了,在调用板子之前先合并一下即可。

int fa[maxn];
int tmp[maxn];
int u[maxn], v[maxn], w[maxn];
int n, m;

int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
bool cmp(int i, int j) {
    return w[i] < w[j];
}

int solve() {
    int ans = 0;
    //for (int i = 0; i < maxn; i++) fa[i] = i;
    for (int i = 0; i < m; i++) tmp[i] = i;
    sort(tmp, tmp + m, cmp);
    for (int i = 0; i < m; i++) {
        int e = tmp[i];
        int from = find(u[e]);
        int to = find(v[e]);
        if (from != to) {
            ans += w[e];
            fa[from] = to;
        }
    }
    return ans;
}

int main()
{
    //ios::sync_with_stdio(false);
    //while (cin >> n && n) {
    cin >> n;
    m = 0;
    for (int i = 0; i < maxn; i++) fa[i] = i;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            u[m] = i;
            v[m] = j;
            cin >> w[m];
            m++;
        }
    }
    int q; cin >> q;
    while (q--) {
        int a, b, root1, root2;
        cin >> a >> b;
        root1 = find(a);
        root2 = find(b);
        if (root1 != root2) {
            fa[root1] = root2;
        }
    }
    cout << solve() << endl;
   // }
    return 0;
}
posted @ 2020-08-14 05:54  StreamAzure  阅读(82)  评论(0编辑  收藏  举报