PAT 1021. Deepest Root 不狗血,无剧情(关于函数的堆的大小限制)
2014-11-19 12:10
483 查看
“喜闻乐见”的遇到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;
简单的想法就是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 link Link 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 DEBUG int i; for(i=1; i<=n; ++i) printf("%d ", pointto[i]); printf("\n"); #endif } int main(void) { #ifdef DEBUG freopen("in.txt", "r", stdin); #endif scanf("%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 node for(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; } // output qsort(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; }
相关文章推荐
- 关于get与post传递参数容量大小限制区别以及curl函数与file_get_contents的区别(面试)
- 关于eWebEditor突破上传图片大小限制的问题
- 限制网页图片大小JS函数
- java关于向数据库存入文件大小受限制的问题.
- 浙大PAT 1021题 1021. Deepest Root
- 关于文件上传大小限制的总结
- 关于 select() 时的 FD_SETSIZE 大小限制
- struts2关于文件上传限制文件上传大小问题
- [Oracle数据库] 急!关于在AIX4.3.3版本下导8.0.5数据库DMP文件大小的限制!
- 关于FileUpload文件上传的文件大小限制问题
- PAT 1021. Deepest Root
- 关于上传文件的大小限制
- 关于j2me中RMS的大小限制
- 关于exe中导出函数限制的疑惑
- C语言 全局变量和局部变量的大小限制(关于堆栈的划定)
- 关于如何限制exchange可上传附件大小的讨论
- 关于outlook 2003 PST文件大小限制管理
- 关于j2me中RMS的大小限制
- 关于修改extmail附件大小限制的位置
- 关于插件KindEditor 上传图大小的限制