UVA548 tree的思路

Posted on 2018-10-22 20:30  亦辰落  阅读(208)  评论(0编辑  收藏  举报

唔,首先这题给出了中序遍历和后序遍历要求我们求出,

一个叶子节点到根的数值总和最小,且这个叶子节点是最小的那个

这题的难点在于如何运用中序遍历和后序遍历还原整棵树,

这里有两个方法:

1. 递归构造原树。
1. 运用链表构造一棵树。

我将要运用的是链表构造树。

#include<bits/stdc++.h> 

using namespace std;

struct Node{
   int v;
   Node *left,*right;
};//首先利用结构体构造树的节点 

Node *root;//申请根节点 
Node *newnode() {return new Node();}//添加新的节点 

const int inf=0x7fffffff;//设定值最大 
const int maxn=10000+10;
int p[maxn],i[maxn],n,ok,b,best;
 
bool read(int *a)//读入数据,进行存储 
{
    string s;
    if(!getline(cin,s)) return false;//输入进树的节点数 
    stringstream tf(s);
    int x;n=0;
    while(tf>>x) a[n++]=x;
    return n>0;
}
 
Node* bulid(int l1,int r1,int l2,int r2)//构造树的节点 
{
    if(l1>r1) return NULL;//null==空,所以空数返回空 
    Node *t=newnode();//申请节点 
    t->v=p[r2];//运用链表 
    int p=l1;
    while(i[p]!=t->v) p++;//添加子树 
    int cnt=p-l1;
    t->left=bulid(l1,p-1,l2,l2+cnt-1);
    t->right=bulid(p+1,r1,l2+cnt,r2-1);//构造左右子树 
    return t;
}
 
void dfs(Node *t,int sum)//用深搜寻找最小值的终端叶子 
{
    sum+=t->v;
    if(!t->left&&!t->right){//检寻左右子树 
        if(sum<b||(sum==b&&t->v<best)){
              b=sum;best=t->v;
        }
    }
    if(t->left) dfs(t->left,sum);
    if(t->right) dfs(t->right,sum);//搜索回溯 
}
 
int main()
{
    while(read(i)){//输入 
        read(p);
        b=inf;best=inf;
        root=bulid(0,n-1,0,n-1);
        dfs(root,0);//从根节点开始搜 
        printf("%d\n",best);
    }
} 

就是这个样子啦!!!