现在的位置: 首页 > 综合 > 正文

ZJU 1990 Subway tree systems – 树的最小表示

2018年05月02日 ⁄ 综合 ⁄ 共 1700字 ⁄ 字号 评论关闭

题目大意:

初始时站在树的根节点,若朝着远离根的方向走,记录“0”,接近根的方向走记录“1”。并且树的每一条边只能来回走一次(即向下和返回)。一个合法的01序列可以描述出一棵树的形态。现在给出两个合法的01序列,判断两棵树是否同构。

分析:

由于根节点确定,若两棵树同构,无非就是把子树的位置交换了一下。很自然的想法就是:将树的子树按照某种规则进行排序,若排序之后两个字符串相等,则同构;否则不同构。

现在来分析一下01序列,可以看出,当一个串的“0”和“1”个数相等时,恰好就是一棵子树。例如:

0010011101001011

可以划分为一下三棵子树

00100111,01,001011

而对于每部分划分来说,去掉第一个0和末尾的1,得到的就遍历是这棵子树的01序列(空串表示子树为空)。这样便出现了递归结构

将这棵树最小表示算法描述如下:

0、若01序列为空,返回。

1、划分出该01序列的每一棵子树。

2、对于每棵子树,去掉第一个0和末尾1之后,递归进行最小表示。

3、得到每棵子树的最小表示后,将子树的01串按照strcmp排序。

 

  1. /*
  2. ZJU1990 Subway tree systems
  3. */
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7. #define N 3005
  8. typedef struct{
  9.     int f,len;
  10. }Node;
  11. Node bm[N/2][N/2];
  12. int nbm;
  13. char temp[N],*sp;
  14. int cmp(const void *A,const void *B){
  15.     Node a = *((Node*)A);
  16.     Node b = *((Node*)B);
  17.     int i,m=(a.len>b.len?b.len:a.len);
  18.     for(i=0;i<m;i++){
  19.         if(sp[a.f+i]!=sp[b.f+i])
  20.             return sp[a.f+i] - sp[b.f+i];
  21.     }
  22.     return 0;
  23. }
  24. void MinRep(char s[],int n){
  25.     int i,j,k,m=0,count=0;
  26.     Node *b=&bm[nbm++][0];
  27.     if(n<=0) return;
  28.     
  29.     for(i=0;i<n;i++){
  30.         if(count==0) b[m].f=i;
  31.         if(s[i]=='0') count++;
  32.         else count--;
  33.         if(count==0) {
  34.             b[m].len=i-b[m].f+1;
  35.             m++;
  36.         }
  37.     }
  38.     
  39.     for(k=0;k<m;k++) Min(s+b[k].f+1,b[k].len-2);
  40.     
  41.     sp=s;
  42.     qsort(b,m,sizeof(Node),cmp);
  43.     
  44.     for(i=k=0;k<m;k++){
  45.         for(j=0;j<b[k].len;j++,i++)
  46.             temp[i]=s[b[k].f+j];
  47.     }
  48.     for(i=0;i<n;i++) s[i]=temp[i];
  49.     
  50. }
  51. int main()
  52. {
  53.     int i,j,k,T;
  54.     char s[N];
  55.     char t[N];
  56.     
  57.     scanf("%d",&T);
  58.     while(T--){
  59.         scanf("%s%s",s,t);
  60.         nbm=0;
  61.         MinRep(s,strlen(s));
  62.         nbm=0;
  63.         MinRep(t,strlen(t));
  64.         if(strcmp(s,t)==0) puts("same");
  65.         else puts("different");
  66.     }
  67.     
  68.     return 0;
  69. }

抱歉!评论已关闭.