题目是把一个普通树转化为二叉树,发现用邻接表可以很好地同时表示孩子和兄弟的关系。因为输入用深度优先搜索,采取了同时记录父节点和孩子信息的双向节点结构。
每个节点的格式为 (父亲,自己的编号,孩子)
题目:openjudge 6308
http://jmusoft.openjudge.cn/beida/09/
-
总时间限制:
- 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
#include <iostream>
#include <cstring>
using namespace std;
typedef struct node{
int p,num;
node *ne;
}node;
typedef struct node2{
int l,r;
}node2;
node tr[10010];
node2 tr2[100010];
void dfs(int i,int d,int &h){
h=max(h,d);
if(tr2[i].l!=-1)
dfs(tr2[i].l,d+1,h);
if(tr2[i].r!=-1)
dfs(tr2[i].r,d+1,h);
}
int main(){
string s;
cin>>s;
int n=1;
while(s!="#"){
for(int i=0;i<10010;i++){
tr[i].p=-1;
tr[i].num=i;
tr[i].ne=NULL;
}
int t=0,tm=0;
node *p,*q;
int count=0,c=0;;
for(int i=0;i<s.length();i++){
if(s[i]=='d'){
p=&tr[tm];
while(p->ne!=NULL){
p=p->ne;
}
q=new node;
q->p=tm;
q->num=++t;
q->ne=NULL;
p->ne=q;
tr[t].p=tm;
tm=t;
c++;
}else{
tm=tr[tm].p;
c--;
}
count=max(count,c);
}
memset(tr2,-1,sizeof(tr2));
for(int i=0;i<=t;i++){
p=tr[i].ne;
if(p!=NULL){
tr2[i].l=p->num;
int j=p->num;
while(p->ne!=NULL){
p=p->ne;
while(tr2[j].r!=-1){
j=tr2[j].r;
}
tr2[j].r=p->num;
}
}
}
int h=0;
dfs(0,0,h);
cout<<"Tree "<<n++<<": "<<count<<" => "<<h<<endl;
cin>>s;
}
return 0;
}