poj 树的转换

树的转换

总时间限制:5000ms内存限制:65536kB描述

我们都知道用“左儿子右兄弟”的方法可以将一棵一般的树转换为二叉树,如:

    0                             0
  / | \                          /
 1  2  3       ===>             1
   / \                           \
  4   5                           2
                                 / \
                                4   3
                                 \
                                  5

现在请你将一些一般的树用这种方法转换为二叉树,并输出转换前和转换后树的高度。

输入输入包括多行,最后一行以一个#表示结束。
每行是一个由“u”和“d”组成的字符串,表示一棵树的深度优先搜索信息。比 如,dudduduudu可以用来表示上文中的左树,因为搜索过程为:0 Down to 1 Up to 0 Down to 2 Down to 4 Up to 2 Down to 5 Up to 2 Up to 0 Down to 3 Up to 0。
你可以认为每棵树的结点数至少为2,并且不超过10000。输出对于每棵树,按如下格式输出转换前和转换后树的高度:
Tree t: h1 => h2
其中t是树的编号(从1开始),h1是转换前树的高度,h2是转换后树的高度。样例输入
dudduduudu
ddddduuuuu
dddduduuuu
dddduuduuu
#
样例输出
Tree 1: 2 => 4
Tree 2: 5 => 5
Tree 3: 4 => 5
Tree 4: 4 => 4
//similar to dp

#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#define maxn 40005//maxn should be bigger than the count of nodes



int main()
{
	char chp_temp[maxn];
	int ori_depth = 0, fa[maxn] = {0}, m_dep = 0, m_dep2 = 0, dep[maxn] = {0}, chd[maxn] = {0};//dep record bitree depth, chd record the count of children

	//ori_depth record current tree depth(not bitree)

	int t = 0;
	while (true)
	{
		++t;
		scanf("%s", chp_temp);
		int len = strlen(chp_temp);

		if (!len) //no need (node > 2)
		{
			printf("Tree %d: 0 => 0\n", t);
			continue;
		}
		if (chp_temp[0] == '#') break;


		ori_depth = 0;//init
		memset(chd, 0, sizeof(chd));
		memset(dep, 0, sizeof(dep));
		memset(fa, 0, sizeof(fa));
		m_dep = 0;
		m_dep2 = 0;


		for (int i = 1; i <= len; ++i)
		{
			char ch = chp_temp[i - 1];
			if (ch == 'd')
			{
				++ori_depth;
				if (m_dep < ori_depth) m_dep = ori_depth;

				fa[i] = i - 1;
				dep[i] = dep[i - 1] + chd[i-1] + 1;
				++chd[i - 1];
				if (m_dep2 < dep[i]) m_dep2 = dep[i];
			}
			else if (ch == 'u')
			{
				--ori_depth;
				dep[i] = dep[fa[i-1]];
				chd[i] = chd[fa[i-1]];
				fa[i] = fa[fa[i-1]];
			}
		}
		printf ("Tree %d: %d => %d\n", t, m_dep, m_dep2);
	}
	return 0;
}

转载于:https://my.oschina.net/locusxt/blog/173639

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值