ZOJ3965 给定一颗二叉树的两种DFS序列 输出一种可能的二叉树的结构。

考察树的递归性质,不要想的太复杂。

当前节点在两个串中后面的节点假如不同则能确认两个子树,如果相同则把下个点作当前点的一个儿子。如果子树中还有未连根的点则接到当前点下。son数组表示每个点的子树有多少个点。pos数组记录每个数在每个序列中的位置。dfs中p1,p2指向同一个数

lim1,lim2表示当前点子树可能最大的子树范围。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>


using namespace std;  
#define maxn 110000  
int n,fa[maxn];  
int s1[maxn],s2[maxn];  
int pos1[maxn],pos2[maxn];  
int vis[maxn],son[maxn];  
void dfs(int p1,int p2,int lim1,int lim2)  
{  
    //printf("%d %d %d %d\n:::::\n",p1,lim1,p2,lim2);  
    //system("pause");  
    int now=s1[p1];  
    if(vis[now]) return;  
    vis[now]=1;  
    if(p1<=0||p1>n) return ;  
    if(p2<=0||p2>n) return ;  
    if(lim1<=0) return ;  
    if(lim2<=0) return ;  
    if(p1>lim1||p2>lim2) return;  
    son[now]=1;  
    if(lim1==p1||lim2==p2) return;  
    int r1=lim1,r2=lim2;  
    if(s1[p1+1]!=s2[p2+1]&&p1+1<=lim1&&p2+1<=lim2)  
    {  
        int len=0;  
        if(!fa[s1[p1+1]])  
        {  
            fa[s1[p1+1]]=now;  
            r1=pos1[s2[p2+1]]-1;  
            len=r1-p1;  
            dfs(p1+1, pos2[ s1[p1+1] ] , r1 ,pos2[ s1[p1+1] ]+len-1  );  
            son[now]+=son[ s1 [p1+1] ];  
        }  
        if(!fa[s2[p2+1]])  
        {  
        fa[s2[p2+1]]=now;  
        r2=pos2[s1[p1+1]]-1;  
        len=r2-p2;  
        dfs( pos1[s2[p2+1]] , p2+1, pos1[s2[p2+1]]+len-1, r2 );  
        son[now]+=son[ s2 [p2+1] ];  
        }  
    }  
    else if(s1[p1+1]==s2[p2+1]&&p1+1<=lim1&&p2+1<=lim2)  
    {  
        fa[ s1[p1+1] ] = now;  
        dfs(p1+1,p2+1,lim1,lim2);  
        son[now]+=son[ s1[p1+1] ];  
        int nt=p1+son[s1[p1+1]]+1;  
        if(son[now]<lim1-p1+1)  
        {  
            fa[s1[nt]]=now;  
            dfs(nt,pos2[s1[nt]],lim1,lim2);  
            son[now]+=son[s1[nt]];  
        }  
    }  
}  
  
int main()  
{  
    int cas;  
    scanf("%d",&cas);  
    while(cas--)  
    {  
        scanf("%d",&n);  
        memset(fa,0,sizeof(fa));  
        memset(vis,0,sizeof(vis));  
        memset(son,0,sizeof(son));  
        memset(s1,0,sizeof(s1));  
        memset(s2,0,sizeof(s2));  
        memset(pos1,0,sizeof(pos1));  
        memset(pos2,0,sizeof(pos2));  
        for(int i=1;i<=n;i++) scanf("%d",&s1[i]),pos1[s1[i]]=i;  
        for(int i=1;i<=n;i++) scanf("%d",&s2[i]),pos2[s2[i]]=i;  
        dfs(1,1,n,n);  
        for(int i=1;i<n;i++) printf("%d ",fa[i]);  
        printf("%d\n",fa[n]);  
    }  
    return 0;  
}  

  

posted on 2017-04-27 21:26  Bingsen  阅读(345)  评论(0编辑  收藏  举报