pku 2201 Cartesian Tree(笛卡尔树)

//985MS,不知道NO是怎么产生的???
#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace std;

#define MAXN 50010

struct TNode
{
    int key,fix,idx;
};
TNode node[MAXN];

struct ANode
{
    int p,l,r;
};
ANode ans[MAXN];

inline bool mycmp(const TNode &n1,const TNode &n2)
{
    return n1.key<n2.key;
}

int n,root,par[MAXN],lc[MAXN],rc[MAXN];
bool ok;

bool build()
{
    int i,last;
    root=1;
    par[1]=lc[1]=rc[1]=0;
    ans[ node[1].idx ].p=ans[ node[1].idx ].l=ans[ node[1].idx ].r=0;
    for(i=2; i<=n; i++)
    {
        //最小堆
        last=i-1;
        par[i]=lc[i]=rc[i]=0;
        ans[ node[i].idx ].p = ans[ node[i].idx ].l = ans[ node[i].idx ].r = 0;
        while(last != 0)
        {
            if(node[last].fix == node[i].fix) return false;//不知道NO是不是这样产生的,不过这题没有NO的情况,因为每个fix都不同!!
            if(node[last].fix > node[i].fix)
            {
                //左旋
                ans[ node[last].idx ].r = node[ lc[i] ].idx;
                ans[ node[last].idx ].p = node[ i ].idx;
                ans[ node[ lc[i] ].idx ].p = node[ last] .idx;
                ans[ node[i].idx ].p = node[ par[last] ].idx;
                ans[ node[i].idx ].l = node[last].idx;
                par[i]=par[last];
                if(par[i]==0) root=i;
                rc[last]=lc[i];
                lc[i]=last;
                last=par[last];
            }
            else
            {
                //直接连接
                ans[ node[last].idx ].r = node[i].idx;
                ans[ node[i].idx ].p = node[last].idx;
                par[i]=last;
                rc[last]=i;
                break;
            }
        }
    }
    return true;
}

void showtree(int r)
{
    if(lc[r] != 0) showtree(lc[r]);

    printf("(%d,%d)\n",node[r].key,node[r].fix);

    if(rc[r] != 0) showtree(rc[r]);
}

int main()
{
    int i;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=1; i<=n; i++)
        {
            scanf("%d %d",&node[i].key,&node[i].fix);
            node[i].idx=i;
        }
        sort(node+1,node+n+1,mycmp);
        if( ! build() ) printf("NO\n");
        else
        {
            printf("YES\n");
            //   showtree(root);
            for(i=1; i<=n; i++) printf("%d %d %d\n",ans[i].p,ans[i].l,ans[i].r);
        }
    }
    return 0;
}

 

posted @ 2010-08-23 23:48  菜到不得鸟  阅读(462)  评论(0)    收藏  举报