求最近祖先和最近祖先树所含节点个数问题--三星研究院

You are to find the closest common ancestor of two vertices in a binary tree. For example, the common ancestors of vertices 8 and 13 in the figure below are vertices 3 and 1. Among them, vertex 3 is the closest to the vertex 8 and 13. And the size of sub-tree (the number of vertices in the sub-tree) rooted by vertex 3 is 8.

Given a binary tree and two vertices, write a program that finds the closest common ancestor and computes the size of the sub-tree rooted by the closest common ancestor. No input is given where one of the two given vertices is an ancestor of the other. For example, ‘11 and 3’ in the above tree is an invalid input. Therefore, your program does not have to consider this case.

 

[Constraints]

The number of vertices are from 3 to 10000

 

 

[Input]

You are given 10 test cases. Each test case has two lines, so the total number of lines is 20. In each test case, the first line consists of four integers, V (the number of vertices in the tree), E (the number of edges), and the indices of two vertices. E edges are listed in the next line. Each edge is represented by two vertices; the index of the parent vertex always precedes the index of the child. For example, the edge connecting vertices 5 and 8 is represented by “5 8”, not by “8 5.” There is no order in which the edges are given. Every consecutive integer in the input is separated by a space. 

 

  

Given 10 test cases,

First 4 test cases contain small number of vertices(3, 5, 7, 10 each).

Next 6 test cases contain same or greater than 50 vertices.

 

 

The indices of vertices are integers from 1 to V, and root vertex always has the index 1.

It is guaranteed that the parent vertex has smaller index than the child vertex.

In this problem, it is not important whether the child is the left child of the parent or the right child; so you can decide this arbitrarily.

 

 

[Output]

Output 10 answers in 10 lines. Each line starts with ‘#x’ meaning the index of a test case, and writes the answer after a space. The answer has two integers: the index of the closest common ancestor and the size of the sub-tree rooted by the closest common ancestor. These two integers are separated by a space as well. 

 

   

[I/O Example]

Input (20 lines in total)

13 12 8 13 Start of the first input

1 2 1 3 2 4 3 5 3 6 4 7 7 12 5 9 5 8 6 10 6 11 11 13

10 9 1 10 Start of the second input

1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10

...

Output (10 lines in total)

#1 3 8

#2 1 10

...

#include <stdio.h>
#include <math.h>

int i=0,j=0;

int main()
{
    
 int ac,N,edge,nod1,nod2;#ac最近祖先节点编号
 int buildb(int a[],int b[][5],int N,int edge);//重构数组,保存b数组第0-3列。0该节点,1左孩子,2右孩子 3 父节点
 int high(int b[][5],int t);//求节点高度
 int conod(int b[][5],int t);//求以t为根的树所含的节点数量。
 int find(int b[][5],int nod1,int nod2);//找出最近祖先节点编号
 
 
 for(j=0; j<10;j++ ){
    scanf("%d %d %d %d\n",&N,&edge,&nod1,&nod2);
    int a[edge*2],b[N+1][5];//0该节点,1左孩子,2右孩子 3 父节点 4节点高度
    
    for(i = 0;i<edge;i++){
    	
    	scanf("%d %d ",&a[i*2],&a[1+i*2]);
     }
     scanf("\n");
     
    buildb(a,b,N,edge); 
    
    for(i = 1;i<N+1;i++){
        //printf("%d %d %d %d",b[i][0],b[i][1],b[i][2],b[i][3]);
        b[i][4] = high(b,i);
    }
    
    ac = find(b,nod1,nod2);
    printf("#%d %d %d\n",j+1,ac,conod(b,ac));
    
 }
 
 return 0;
}


int buildb(int a[],int b[][5],int N,int edge){
    
    
    for(i=0;i<N+1;i++){
        b[i][0] = i;b[i][1]=0;b[i][2]=0;b[i][3]=0;b[i][4]=0;
    }
    for(i=0;i<edge;i++){
        if(b[a[i*2]][1] == 0)
           b[a[i*2]][1] = a[i*2+1];
        else{
            b[a[i*2]][2] = a[i*2+1];
        }
        b[a[i*2+1]][3] = a[i*2];
        
    }
   
}


int high(int b[][5],int t){//递归 获取层数 
    if(t==1&t==0)
        return 1;
        
    else
        return high(b,b[t][3])+1;
}

int conod(int b[][5],int t){
    if(b[t][1]==0&b[t][2]==0){
        return 1;
    }
    else if(b[t][2]==0){
        return conod(b,b[t][1])+1;
    }
    else
       return conod(b,b[t][1])+conod(b,b[t][2])+1; 
}

int find(int b[][5],int nod1,int nod2){
    int n;
    n = b[nod1][4] - b[nod2][4];
    if(n < 0){
        n = -n;
        for(i = 0;i < n;i++){
            nod2 = b[nod2][3];
        }
        
    }
    else{
        for(i = 0;i < n;i++){
            nod1 = b[nod1][3];
        }
    }
    for(i = b[nod1][4];i > 0;i--){
        if(nod1 == nod2)
            return nod1;
        else{
            nod1 = b[nod1][3];
            nod2 = b[nod2][3];
        }
    }      
}


还有个bug没解决。。。

内存访问错误问题。

猜你喜欢

转载自blog.csdn.net/u011537121/article/details/83384775