[POJ2201]Cartesian Tree
题意
给你每个节点的a与k两个权值,问能否建出一棵笛卡尔树,满足对于一个节点他所有右儿子的k值小于其k值,所有左儿子的k值大于其k值,且其祖先的a值小于其a值。若可以,输出每个节点的父节点,右儿子,左儿子。
题解
因为题目保证所有的a各不相同,k各不相同,故一定可以建立出一棵符合条件的笛卡尔树,直接建树即可。(排序后的标号处理有点麻烦。。。)
注意POJ这里不能用万能头文件
代码
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN=5e4+5;
int st[MAXN],N;
struct node{
int k,a;
int id;
}p[MAXN];
struct tree{
int fa;
int l,r;
}tr[MAXN];
bool cmp(node x,node y){
return x.k<y.k;
}
int main(){
scanf("%d",&N);
for(int i=1;i<=N;i++){
scanf("%d%d",&p[i].k,&p[i].a);
p[i].id=i;
}
sort(p+1,p+1+N,cmp);
int top=1;
st[top]=1;
for(int i=2;i<=N;i++){
while(top&&p[st[top]].a>p[i].a) top--;
if(!top){
tr[p[st[1]].id].fa=p[i].id;
tr[p[i].id].l=p[st[1]].id;
}else{
tr[p[i].id].l=tr[p[st[top]].id].r;
tr[tr[p[i].id].l].fa=p[i].id;
tr[p[i].id].fa=p[st[top]].id;
tr[p[st[top]].id].r=p[i].id;
}
st[++top]=i;
}
puts("YES");
for(int i=1;i<=N;i++){
printf("%d %d %d\n",tr[i].fa,tr[i].l,tr[i].r);
}
return 0;
}

浙公网安备 33010602011771号