4 - 09. 笛卡尔树(25)

来源:互联网 发布:spsss软件如何安装 编辑:程序博客网 时间:2024/04/29 15:17

4 - 09. 笛卡尔树(25)题目地址

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
笛卡尔树是一种特殊的二叉树,其结点包含两个关键字K1和K2。首先笛卡尔树是关于K1的二叉搜索树,即结点左子树的所有K1值都比该结点的K1值小,右子树则大。其次所有结点的K2关键字满足优先队列(不妨设为最小堆)的顺序要求,即该结点的K2值比其子树中所有结点的K2值小。给定一棵二叉树,请判断该树是否笛卡尔树。

输入格式说明:

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

输出格式说明:

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

样例输入与输出:

序号 输入 输出
1
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
2
6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 11 -1 4
15 22 -1 -1
50 35 -1 -1
NO
3
7
8 27 5 1
9 40 -1 -1
10 20 0 3
12 22 -1 4
15 21 6 -1
5 35 -1 -1
13 23 -1 -1
NO
4
6
8 27 5 1
9 40 -1 -1
10 20 0 3
12 21 -1 4
11 22 -1 -1
5 35 -1 -1
NO
5
9
11 5 3 -1
15 3 4 7
5 2 6 0
6 8 -1 -1
9 6 -1 8
10 1 2 1
2 4 -1 -1
20 7 -1 -1
12 9 -1 -1
NO
6
1
1 1 -1 -1
YES

  • 用到了并查集,建立二叉树,二叉树中根遍历,使用队列queue<>判断小堆树
  • 保证40分钟内完成,需要经常敲(我花了将近50分钟敲下面的代码直接敲)
/*4 - 09. 笛卡尔树(25)http://www.patest.cn/contests/ds/4-09*/#include <iostream>  #include <stdio.h>#include <stdlib.h>#include <vector>#include <string>#include <string.h>#include <algorithm>#include <queue>using namespace std;#define N 1001int n;struct mydata{    int k1;    int k2;    int left;    int right;    mydata(int _k1=0, int _k2=0, int _left=-1, int _right=-1) :k1(_k1), k2(_k2), left(_left), right(_right){}};typedef struct node{    int k1, k2;    struct node* left;    struct node* right;    node(int _k1 = 0, int _k2 = 0) :k1(_k1), k2(_k2), left(NULL), right(NULL){}}BNode;int father[N];mydata datas[N];int find(int x){    if (x == father[x])        return x;    return father[x] = find(father[x]);}void merg(int x, int y) // 并查集合并{    father[find(y)] = find(x);}BNode* root;BNode* createTreeK1(BNode* root, int i){    if (root == NULL)    {        root = new node(datas[i].k1,datas[i].k2);        if (datas[i].left != -1)        {            root->left = createTreeK1(root->left, datas[i].left);        }        if (datas[i].right != -1)        {            root->right = createTreeK1(root->right, datas[i].right);        }    }    return root;}// 中根遍历vector<int> vin;void inorder(BNode* root){    if (root != NULL)    {        inorder(root->left);        vin.push_back(root->k1);        inorder(root->right);    }}bool isXiaodui(BNode* root) // 小根堆判断{    queue<BNode*> que;    while (!que.empty())    {        que.pop();    }    que.push(root);    while (!que.empty())    {        BNode* rt = que.front();        que.pop();        int data = rt->k2;        if (rt->left != NULL)        {            if (rt->left->k2 <= data)                return false;            que.push(rt->left);        }        if (rt->right != NULL)        {            if (rt->right->k2 <= data)                return false;            que.push(rt->right);        }    }    return true;}int main(){    //freopen("in", "r", stdin);    while (scanf("%d", &n) != EOF)    {        int i;        for (i = 0; i < n; i++)        {            father[i] = i;        }        for (i = 0; i < n; i++)        {            scanf("%d%d%d%d", &datas[i].k1, &datas[i].k2, &datas[i].left, &datas[i].right);            if (datas[i].left != -1)            {                if (find(i) != find(datas[i].left))                    merg(i, datas[i].left);            }            if (datas[i].right != -1)            {                if (find(i) != find(datas[i].right))                    merg(i, datas[i].right);            }        }        int rootNum = find(0);        root = NULL;        root = createTreeK1(root, rootNum);        vin.clear();        inorder(root);        bool flag1 = true;        for (i = 1; i < n; i++)        {            if (vin[i] <= vin[i - 1]) // 后面的 不大于 前面的就不是了            {                flag1 = false;                break;            }        }        if (flag1)        {            bool flag2 = isXiaodui(root);            if (flag2)            {                printf("YES");            }            else{                printf("NO");            }        }        else{            printf("NO");        }        printf("\n");    }    return 0;}
0 0
原创粉丝点击