2045607 2006-08-27 22:32:59 Accepted 1789 C++ 00:00.02 668K St.Crux 2045606 2006-08-27 22:32:16 Accepted 1789 C++ 00:00.02 556K St.Crux 上面那个是优化过的,没看错.......可能数据碰巧不喜欢这样被优化。 这是标准解法。 #include <cstdio>#include <string> int p[30001], r[30001], n, m, t, x, y, ans; int findset(int i){ if(i == -1 || i >= n) return -1; if(p[i] != -1 && p[i] != i) p[i] = findset(p[i]); return p[i];} int ufs(int a, int b){ a = findset(a); b = findset(b); if(a == b) return a; if(a == -1) return b; if(b == -1) return a; if(r[a] < r[b]) { p[a] = b; return b; } else { if(r[a] == r[b]) r[a] ++; p[b] = a; return a; }} void init(){ memset(r, 0, sizeof(r)); int i; for(i = 0; i < n; i ++) { p[i] = -1; }} int main(){ //freopen("in.txt", "r", stdin); while(scanf("%d %d", &n, &m) && n) { int i, k; init(); for(i = 0; i < m; i ++) { scanf("%d", &t); scanf("%d", &x); if(p[x] == -1) p[x] = x; for(k = 1; k < t; k ++) { scanf("%d", &y); if(p[y] == -1) p[y] = y; ufs(x, y); } } ans = 1; if(p[0] != -1) { for(i = 1; i < n; i ++) { if(findset(i) == findset(0)) ans ++; } } //pt(); printf("%d\n", ans); } return 0;} 在WrongAnswer一个多钟头以及顺便看完了PLU的SC总决赛后,换了种简单的写法,AC了。并且找到了原来的错误。 #include <cstdio>#include <string> int p[30001], n, m, t, x, y, ans; int findset(int i){ if(p[i] != i) p[i] = findset(p[i]); return p[i];} void init(){ int i; for(i = 0; i < n; i ++) { p[i] = i; }} int main(){ //freopen("in.txt", "r", stdin); while(scanf("%d %d", &n, &m) && n) { int i, k; init(); for(i = 0; i < m; i ++) { scanf("%d", &t); scanf("%d", &x); x = findset(x); for(k = 1; k < t; k ++) { scanf("%d", &y); if(x != findset(y)) p[findset(y)] = x; } } ans = 1; for(i = 1; i < n; i ++) { if(findset(i) == findset(0)) ans ++; } //pt(); printf("%d\n", ans); } return 0;}

评论