题目链接。
解题报告:
就是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; }