HDU1102Constructing Roads(最小生成树, Kruskal)

题目链接

解题报告:

就是Kruskal就行了。。不过WA了很多次。

第一个致命错误是。。数据会有很多组(无语了)。。

第二个错误是。。

for(i=0; i<q; i++){
    scanf("%d %d", &a, &b);
    int x = find(a), y = find(b);
    p[x] = y;
}

错写成了

for(i=0; i<q; i++){
    scanf("%d %d", &a, &b);
    p[a] = b;
}

只能说对于并查集理解的并不是十分透彻。。

例如,对于1 2, 1 3这两组数据, 操作p[1] = 2, p[1] = 3,1-2这条路便被覆盖掉了。用并查集后便成了p[1] = 2, p[2] =3;这样1,2,3便是连通的。。

以下是AC代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXN 10000

int u[MAXN], v[MAXN], r[MAXN], w[MAXN], p[MAXN];

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

int cmp(const void *a, const void *b){
    int x = *(int *)a, y = *(int *)b;
    return w[x] - w[y];
}

int main(){
    int n, m, q, i, j, t, a, b, ans;
    while(scanf("%d", &n) == 1){
        m = 0, ans = 0;
        for(i=1; i<=n; i++){
            for(j=1; j<=n; j++){
                scanf("%d", &t);
                if(j<i && t != 0){
                    u[m] = i;
                    v[m] = j;
                    w[m++] = t;
                }
            }
        }
        for(i=1; i<=n; i++) p[i] = i;
        for(i=0; i<m; i++) r[i] = i;
        qsort(r, m, sizeof(r[0]), cmp);
        scanf("%d", &q);
        for(i=0; i<q; i++){
            scanf("%d %d", &a, &b);
            int x = find(a), y = find(b);
            p[x] = y;
        }
        for(i=0; i<m; i++){
            int e = r[i], x = find(u[e]), y = find(v[e]);
            if(x != y){
                ans += w[e]; p[x] = y;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/tanhehe/p/2912588.html