POJ 2201 Cartesian Tree ——笛卡尔树

【题目分析】

    构造一颗笛卡尔树,然后输出这棵树即可。

    首先进行排序,然后用一个栈维护最右的树的节点信息,插入的时候按照第二关键字去找,找到之后插入,下面的树成为它的左子树即可。

    然后插入分三种情况讨论(最下面,中间,成为了新的树根)

【代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
struct node{
	int k,a,id;
}a[50005],st[50005];
int ans[50005][3];
int cmp(node a,node b)
{return a.k<b.k;}
int n;
void solve()
{
	node now;
	int top=0,x,y,z;
	st[top++]=a[1];
	for (int i=2;i<=n;++i)
	{
		int flag=0;
		while (top>0&&st[top-1].a>a[i].a)
		{
			flag=1;
			now=st[--top];
		}
		if (!flag)
		{
			x=st[top-1].id;
			y=a[i].id;
			ans[x][2]=y;
			ans[y][0]=x;
			st[top++]=a[i];
		}
		else
		{
			if (top)
			{
				x=st[top-1].id;
				y=a[i].id;
				z=now.id;
				ans[x][2]=y;
				ans[y][0]=x;
				ans[z][0]=y;
				ans[y][1]=z;
				st[top++]=a[i];
			}
			else
			{
				y=a[i].id;
				z=now.id;
				ans[y][1]=z;
				ans[z][0]=y;
				st[top++]=a[i];
			}
		}
	}
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;++i)
	{
		scanf("%d%d",&a[i].k,&a[i].a);
		a[i].id=i;
	}
	sort(a+1,a+n+1,cmp);
	solve();
	printf("YES\n");
	for (int i=1;i<=n;++i) printf("%d %d %d\n",ans[i][0],ans[i][1],ans[i][2]);
}

  

posted @ 2016-12-18 18:21  SfailSth  阅读(232)  评论(0编辑  收藏  举报