题目:
树的括号表示法
TimeLimit:1000MS MemoryLimit:128MB
64-bit integer IO format:%lld
Problem Description
HOME_W发明了一种括号表示法来表示二叉树结构
他的递归定义如下,
-
若结点v有左孩子或者右孩子,且左右子树的括号表示分别为A,B。则结点v的括号表示法为 v(A,B)
-
否则 空树用#表示,只有一个结点v的树的括号表示法就是 v
例如树
1
/ \
2 3
/
4
的括号表示法是
1(2(4,#),3)
这种表示法有些优越之处,既保留了二叉树的先序遍历顺序,又存贮了树的结构。方便了树结构在网络上的传输,且解析时甚至不需要重新建立这颗树
现在给你一颗以1为根的二叉树的所有边,请输出这棵树的括号表示法
Input
单组数据
第一行是一个整数n,代表树的结点数。
接下来有n-1行,每行有两个整数a,b代表的a,b之间有一条边。
n<=1e5
1<=a,b<=n
保证输入是一颗合法的二叉树
Output
请输出一行,代表这棵树的括号表示法,由于输出结果可能不唯一,请输出字典序最小的方案
题意修正:这里的字典序是只比较整个数字和#号的
其中大小关系如下:#<1<2<3<……<10<11<……<100<101<……
SampleInput
2 1 2
SampleOutput
1(#,2)
思路:dfs
AC代码:
- #include<cstdio>
- #include<algorithm>
- #include<cmath>
- #include<map>
- #include<vector>
- using namespace std;
- vector<int>e[100005];
- void dfs(int v,int pre){
- vector<int>q;
- for(int i=0;i<e[v].size();i++){
- if(e[v][i]!=pre){
- q.push_back(e[v][i]);
- }
- }
- sort(q.begin(),q.end());
- if(q.size()==0)printf("%d",v);
- else if(q.size()==1){
- printf("%d(#,",v);
- dfs(q[0],v);
- printf(")");
- }
- else{
- printf("%d(",v);
- dfs(q[0],v);
- //printf(",",v);
- printf(",");
- dfs(q[1],v);
- //printf(")",v);
- printf(")");
- }
- }
- int main(){
- int n,l,r,m,i,j,x,y;
- scanf("%d",&n);
- for(int i=1;i<n;i++){
- scanf("%d%d",&x,&y);
- e[x].push_back(y);
- e[y].push_back(x);
- }
- dfs(1,0);
- return 0;
- }