题目大意:给定一个二叉树,求让它成为孩子结点值不大于父亲结点值,同时左孩子结点值小于右孩子结点值。
用广搜建立二叉树,再后序遍历,求最长不下降子序列,我做了一点变化,将左右孩子交换后先序遍历后求最长不上升子序列。
开始超时了,后来把队列用数组实现就行了,不过注意一下没有右孩子时,左孩子可以和父亲结点值相等。


1
//poj 3214
2
#include<iostream>
3
#include<queue>
4
using namespace std;
5
#define N 10000000
6
7
struct Tree
{
8
int v;
9
Tree *left;
10
Tree *right;
11
void init()
{
12
left=0;
13
right=0;
14
}
15
};
16
17
Tree set[N],*p;
18
int n,m,cot,len=1;
19
int b[N];
20
Tree *myque[N];
21
22
void dfs(Tree *q)
23

{
24
int x;
25
x=q->v+cot,m++;
26
//LIS
27
int low=1,high=len,mid;
28
while(low<=high)
{
29
mid=(low+high)/2;
30
if(b[mid]<x) high=mid-1;
31
else low=mid+1;
32
}
33
b[low]=x;
34
if(low>len) len++;
35
36
if(q->right)
37
dfs(q->right);
38
if(q->left)
{
39
if(q->right) cot++; //存在左孩子时才将cot++
40
dfs(q->left);
41
}
42
}
43
44
int main()
45

{
46
int v;
47
int low=0,high=0;
48
n=0;
49
scanf("%d",&m);
50
set[0].init();
51
scanf("%d",&set[0].v);
52
myque[high++]=&set[0];
53
while(scanf("%d",&v)!=EOF)
{
54
p=myque[low++];
55
set[++n].init();
56
set[n].v=v;
57
p->left=&set[n];
58
myque[high++]=p->left;
59
if(scanf("%d",&v)!=EOF)
{ //注意可能不是满二叉树
60
set[++n].init();
61
set[n].v=v;
62
p->right=&set[n];
63
myque[high++]=p->right;
64
}
65
else break;
66
}
67
m=0,cot=0;
68
dfs(&set[0]);
69
printf("%d\n",m-len);
70
return 0;
71
}
72