PAT 1021. Deepest Root 不狗血,无剧情(关于函数的堆的大小限制)

来源:互联网 发布:郑州淘宝诈骗 编辑:程序博客网 时间:2024/04/29 23:33

“喜闻乐见”的遇到BUG。。。

简单的想法就是DFS或者BFS。也可以先用并查集找出树的棵数。我采用了后者,代码结构更清晰。

总共遇到两个BUG,一个是大数据的CASE出错,另一个是第三个CASE出错。

前一个是因为把长度为n的数组定义在了函数内,造成在n接近10^4时出错,应该是数组大小超出了函数可使用的堆大小。经测试,64位ubuntu+gcc 4.8.2下,main函数内在定义2^20 int数组(大约4MB)时运行正常,但在2^21(大约2*10^6)时出现“Segmentation fault”。而非main函数在2^20时就会出错,2^19时不会。

第二个是在find函数里,pointto[fl] = nr。这句在循环图里会产生错误:

5
1 2
2 3
3 4
4 1

这种情况程序会判断只有1棵树,因为pointto数组是“4 4 4 1 5",还少一次更新。正确的写法应该是pointto[fl] = fr;

#include <stdio.h>#include <stdlib.h>#include <stdbool.h>#include <assert.h>int n;typedef struct s_link{int to;struct s_link *nx;}Link;// adjacency linkLink link[10001];int pointto[10001];int roots[10001], pr;int maxDepth;bool bv[10001];int dfs(int root);int cmp(const void *pvl, const void *pvr){return *((int*)pvl) - *((int*)pvr);}int find(int num){if(pointto[num] == num) return num;else return pointto[num] = find(pointto[num]);}void merge(int nl, int nr){int fl = find(nl), fr = find(nr);pointto[fl] = fr;#ifdef DEBUGint i;for(i=1; i<=n; ++i)printf("%d ", pointto[i]);printf("\n");#endif}int main(void){#ifdef DEBUGfreopen("in.txt", "r", stdin);#endifscanf("%d", &n);int i, j;for(i=1; i<=n; ++i)pointto[i] = i;for(i=1; i<n; ++i){int x, y;scanf("%d%d", &x, &y);if(x == y) continue;merge(x, y);Link *pl = (Link*)malloc(sizeof(Link));pl->to = y;pl->nx = link[x].nx;link[x].nx = pl;pl = (Link*)malloc(sizeof(Link));pl->to = x;pl->nx = link[y].nx;link[y].nx = pl;}int cnt=0;for(i=1; i<=n; ++i)if(pointto[i] == i)cnt++;if(cnt > 1){printf("Error: %d components\n", cnt);return 0;}for(i=1; i<=n; ++i){// DFS from every nodefor(j=1; j<=n; ++j)bv[j] = false;int depth = dfs(i);if(depth > maxDepth){maxDepth = depth;roots[0] = i;pr = 1;}else if(depth == maxDepth)roots[pr++] = i;}// outputqsort(roots, pr, sizeof(int), cmp);for(i=0; i<pr; ++i)printf("%d\n", roots[i]);return 0;}int dfs(int root){Link *pl = link[root].nx;int depth = 0, maxd = 0;bv[root] = true;while(pl != NULL){if(!bv[pl->to]){depth = dfs(pl->to);if(maxd < depth)maxd = depth;}pl = pl->nx;}return maxd+1;}



0 0