• 浙大版《数据结构学习与实验指导(第2版)》笛卡尔树


    笛卡尔树

    题目描述

    笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2。首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大。其次所有结点的K2关键字满足优先队列(不妨设为最小堆)的顺序要求,即该结点的K2值比其子树中所有结点的K2值小。给定一棵二叉树,请判断该树是否笛卡尔树。

    输入描述

    输入首先给出正整数N(1<=N<=1000),为树中结点的个数。随后N行,每行给出一个结点的信息,包括:结点的K1值、K2值、左孩子结点编号、右孩子结点编号。设结点从0到(N-1)顺序编号。若某结点不存在孩子结点,则该位置给出−1。

    输出描述

    输出YES如果该树是一棵笛卡尔树;否则输出NO。

    样例

    输入
    6
    8 27 5 1
    9 40 -1 -1
    10 20 0 3
    12 21 -1 4
    15 22 -1 -1
    5 35 -1 -1
    输出
    YES


    思路:

    1. 先利用并查集找到树根,然后从根开始遍历
    2. work1返回的是此节点及其所有子树中所有节点的最大值。根据笛卡尔树定义可得出判断条件:
      • 若当前节点k1 <= work1(a[root].l) 则不是笛卡尔树
      • 若当前节点k1 >= work1(a[root].r) 则不是笛卡尔树
    3. work2返回的是此节点及其所有子树中所有节点的最小值。根据笛卡尔树定义可得出判断条件:
      • 若当前节点k2 >= min(work2(a[root].l),work2(a[root].r)) 则不是笛卡尔树

    Code:

    #include
    using namespace std;
    const int INF = 1e9 + 10;
    const int N = 1e6 + 10;
    struct Node {
    	int k1,k2;
    	int l,r;
    } a[1010];
    int p[1010];
    int find(int x) {
    	return p[x]==x?x:p[x]=find(p[x]);
    }
    bool ok1=1,ok2=1;
    int work1(int root) {
    	int t1,t2;
    	t1=t2=-1;
    	if(a[root].l!=-1) t1 = work1(a[root].l);
    	if(a[root].r!=-1) t2 = work1(a[root].r);
    
    	if(t1!=-1 && a[root].k1<=t1) ok1=0;
    	if(t2!=-1 && a[root].k1>=t2) ok1=0;
    
    	return max(a[root].k1,max(t1,t2));
    }
    int work2(int root) {
    	int t1,t2;
    	t1=t2=INF;
    
    	if(a[root].l!=-1) t1 = work2(a[root].l);
    	if(a[root].r!=-1) t2 = work2(a[root].r);
    
    	if(a[root].k2>=min(t1,t2)) ok2=0;
    
    	return min(a[root].k2,min(t1,t2));
    }
    int main() {
    	int n;
    	cin >> n;
    	for(int i=0; i<n; i++) p[i]=i;
    	for(int i=0; i<n; i++) {
    		cin >> a[i].k1 >> a[i].k2 >> a[i].l >>a[i].r;
    		p[a[i].l] = i;
    		p[a[i].r] = i;
    	}
    	int root;
    	for(int i=0; i<n; i++) {
    		if(find(i)==i) {
    			root=i;
    			break;
    		}
    	}
    	
    	work1(root);
    	work2(root);
    	
    	if(ok1&&ok2) puts("YES");
    	else puts("NO");
    	return 0;
    }
    
    
    /*
    
    
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
  • 相关阅读:
    数据结构简述,时间、空间复杂度,学习网站推荐
    同态加密+区块链,在大健康数据隐私保护中的应用
    NFS服务详解
    【API篇】七、Flink窗口
    夜神模拟器+Fiddler抓包测试App
    你不知道的Python容器
    技术分享 | Jenkins通过什么方式报警?
    小程序经典案例
    el-tabs(标签栏)的入门学习
    Gateway之限流、熔断,Sentinel--服务容错
  • 原文地址:https://blog.csdn.net/m0_51376859/article/details/136636620