POJ 1611 The Suspects 解题报告

    技术2022-06-26  45

    题意就不说了,看了discuss知道用并查集求解。 由于之前没写过并查集,所以找了一本《数据结构》的书复习了下。然后按照书本的描述来写并查集。 没想到在POJ提交代码时却出现了个怪异的现象,老是TLE。 参考网上的解答,改啊改,快崩溃时终于AC了。 真是奇怪,为什么把“判断两个元素的双亲”放在主函数就TLE了呢,而一定要放在unionSet?

    下面是两个版本的代码。 代码一运用了“平行数组”,额外作用了num表示当前集合内的元素个数;而代码二则将当前元素个数存储在根元素。

    代码一:

     

    #include <stdio.h> #define MAX_STU 30000 int parent[MAX_STU]; int num[MAX_STU]; void initSet(int n) { for(int i = 0; i < n; i++) { parent[i] = -1; num[i] = 1; } } unsigned int find(int x) { int r = x; while(parent[r] != -1) r = parent[r]; int temp; while(x != r) { temp = parent[x]; parent[x] = r; x = temp; } return r; } void unionSet(int a, int b) { a = find(a); b = find(b); if(a == b) return ; if(num[b] > num[a]) { parent[a] = b; num[b] += num[a]; } else { parent[b] = a; num[a] += num[b]; } } int main() { int n, m; while(scanf("%d%d", &n, &m), !(n == 0 && m == 0)) { initSet(n); int count, first, stu; for(int i = 0; i < m; i++) { scanf("%d%d", &count, &first); for(int j = 1; j < count; j++) { scanf("%d", &stu); unionSet(first, stu); } } printf("%d/n", num[find(0)]); } return 0; }

    代码二:

    #include <stdio.h> #define MAX_STU 30000 int parent[MAX_STU]; void initSet(int n) { for(int i = 0; i < n; i++) parent[i] = -1; } unsigned int find(int x) { int r = x; while(parent[r] >= 0) r = parent[r]; int temp; while(x != r) { temp = parent[x]; parent[x] = r; x = temp; } return r; } void unionSet(int a, int b) { int aRoot = find(a); int bRoot = find(b); if(aRoot == bRoot) return ; int tmp = parent[aRoot] + parent[bRoot]; if(parent[aRoot] > parent[bRoot]) { parent[aRoot] = bRoot; parent[bRoot] = tmp; } else { parent[bRoot] = aRoot; parent[aRoot] = tmp; } } int main() { int n, m; while(scanf("%d%d", &n, &m), !(n == 0 && m == 0)) { initSet(n); int count, first, stu; for(int i = 0; i < m; i++) { scanf("%d%d", &count, &first); for(int j = 1; j < count; j++) { scanf("%d", &stu); unionSet(first, stu); } } printf("%d/n", -1 * parent[find(0)]); } return 0; }


    最新回复(0)