码迷,mamicode.com
首页 > 其他好文 > 详细

Tree UVA 548

时间:2014-09-07 21:13:15      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:uva   算法   acm   c   源代码   

说说:

    做了这么久,终于做到树了。先说下题意,题目给出了两组数,分别是对一棵树的中序遍历和后序遍历。然后要求的是到达根节点的路径和最短的叶子的值。所谓的路径和就是从叶子到根的路径上所有节点的值的和。这无非就是个树的遍历的问题啦。后序序列的最后一个值为子树根,然后再中序序列中找到该节点,然后树就被分成两棵子树了。然后再递归操作就可以了。这里有一点提醒一下,虽然在开始的时候,对于同一棵树,中序序列和后序序列的起始点都是相同的。但随着不断递归深入,同一棵子树的中序序列和后序序列的各自的起始位置是不同的,因此有必要给递归函数传递四个参数,分别为该子树的中序序列起始点和后序序列起始点。具体操作,看源代码好了。

源代码:

#include <stdio.h>
#define MAXN 10000+5

int post[MAXN];
int in[MAXN];
int min,sum,leaf;

void fun(int,int,int,int);

int main(){
  char c;
  int val,n,i;
//  freopen("data","r",stdin);
  while(1){
    n=0;
    while(scanf("%d%c",&val,&c)&&c!='\n')
      in[n++]=val;
    in[n++]=val;

    n=0;
    while(scanf("%d%c",&val,&c)&&c!='\n')
      post[n++]=val;
    post[n++]=val;

    sum=0;
    min=10000000;//初始最小值设置得尽量大

    fun(0,n-1,0,n-1);
    
    printf("%d\n",leaf);

    if((c=getchar())==EOF)
      break;
    else 
      ungetc(c,stdin);
  }

  return 0;
}

void fun(int pbeg,int pend,int ibeg,int iend){
  int i,num,root;
  int temp=sum;
  sum+=post[pend];

  if(pbeg==pend){//子树仅剩一个节点,到达叶子
    if(sum<min){
     min=sum;
     leaf=post[pend];
     sum=temp;
    }
    else if(sum==min&&post[pend]<leaf)
      leaf=post[pend];
   return ;
  }

  for(num=-1,i=ibeg;i<=iend;i++,num++)//找到树根在中序序列的位置,num=左子树节点的个数-1
    if(in[i]==post[pend]){
      root=i;
      break;
    }

  if(root-1>=ibeg)//左子树非空
    fun(pbeg,pbeg+num,ibeg,root-1);

  if(root+1<=iend)//右子树非空
    fun(pbeg+num+1,pend-1,root+1,iend);

  sum=temp;//注意要回溯
}



Tree UVA 548

标签:uva   算法   acm   c   源代码   

原文地址:http://blog.csdn.net/u011915301/article/details/39121991

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!