您的位置:首页 > 其它

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;

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  PAT c