#求二叉树任意节点之间最短路径#acwing3555#北邮

思路:先读取T,进行T次for循环,每次for循环依次读取m、n,维护一个类型为treenode的动态数组。

1.手动将该数组一号位置的parent设置为null(根节点确定)

2.读取n组数据存入left和right,如果不为-1,则将将其根节点孩子指针和其父指针赋值。若为-1则将根节点的孩子指针置为null

建树完成,再进行m次for循环:

1.读取m组数据存入lhs和rhs,根据动态数组向上逐层找父节点,直到临时指针指向null位置,同时将到根节点路径上所有节点的数值压入动态数组

2.对lhs和rhs分别进行上述操作,得到两个动态数组

3。设置两个整形指针变量l,r分别设为数组最后一个元素从后往前遍历,当a.l=0,b.r=0,c.rvec[r]==lvec[l]跳出循环,返回l+r+2即可

/*给定一个 n个结点(编号 1∼n)构成的二叉树,其根结点为 1号点。进行 m次询问,每次询问两个结点之间的最短路径长度。树中所有边长均为 1。
输入格式
第一行包含一个整数 T,表示共有 T组测试数据。每组数据第一行包含两个整数 n,m。接下来 n行,每行包含两个整数,其中第 i行的整数表示结点 i
的子结点编号。如果没有子结点则输出 −1。接下来 m行,每行包含两个整数,表示要询问的两个结点的编号。
输出格式
每组测试数据输出 m行,代表查询的两个结点之间的最短路径长度。
数据范围
1≤T≤10,1≤n,m≤1000*/
#include <cstdio>
#include <vector>

using namespace std;
struct TreeNode{
    int num;
    TreeNode* right;
    TreeNode* left;
    TreeNode* parent;
};
int main(){
    int T;
    scanf("%d",&T);
    for(int i=0;i<T;++i){
        int n,m;
        scanf("%d%d",&n,&m);
        vector<TreeNode*> nodeArr(n+1);
        for(int j=1;j<=n;++j){
            nodeArr[j]=new TreeNode;
            nodeArr[j]->num=j;
        }

        nodeArr[1]->parent=NULL;
        for(int j=1;j<=n;++j){
            int left,right;
            scanf("%d%d",&left,&right);
            if(left!=-1){
                nodeArr[j]->left=nodeArr[left];
                nodeArr[left]->parent=nodeArr[j];
            }
            else{
                nodeArr[j]->left=NULL;
            }
            if(right!=-1){
                nodeArr[j]->right=nodeArr[right];
                nodeArr[right]->parent=nodeArr[j];
            }
            else{
                nodeArr[j]->right=NULL;
            }
        }
        int lhs,rhs;
        for(int j=0;j<m;++j){
            scanf("%d%d",&lhs,&rhs);
            vector<int> lvec;
            TreeNode* p=nodeArr[lhs];
            while(p!=NULL){
                lvec.push_back(p->num);
                p=p->parent;
            }
            vector<int> rvec;
            p=nodeArr[rhs];
            while(p!=NULL){
                rvec.push_back(p->num);
                p=p->parent; //把从该节点到根节点的全部路径序列插入完成
            }

            int l=lvec.size()-1;
            int r=rvec.size()-1;
            while(true){
                if(l<0||r<0||lvec[l]!=rvec[r]) {
                    break;
                }
                --l;
                --r;
            }
            printf("%d\n",l+r+2);
        }
    }
    return 0;
}

全部评论

相关推荐

评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务