zoukankan      html  css  js  c++  java
  • 洛谷U4727 小L 的二叉树

    U4727 小L 的二叉树

    题目背景

    勤奋又善于思考的小L接触了信息学竞赛,开始的学习十分顺利。但是,小L对数据结构的掌握实在十分渣渣。

    所以,小L当时卡在了二叉树。

    题目描述

    在计算机科学中,二叉树是每个结点最多有两个子结点的有序树。通常子结点被称作“左孩子”和“右孩子”。二叉树被用作二叉搜索树和二叉堆。随后他又和他人讨论起了二叉搜索树。什么是二叉搜索树呢?二叉搜索树首先是一棵二叉树。设key[p]表示结点p上的数值。对于其中的每个结点p,若其存在左孩子lch,则key[p]>key[lch];若其存在右孩子rch,则key[p]<key[rch];注意,本题中的二叉搜索树应满足对于所有结点,其左子树中的key小于当前结点的key,其右子树中的key大于当前结点的key。(因为小L十分喜欢装xx,所以这里他十分装xx的给大家介绍了什么是二叉树和二叉搜索树)。

    可是善于思考的小L不甘于只学习这些基础的东西。他思考了这样一个问题:现在给定一棵二叉树,可以任意修改结点的数值。修改一个结点的数值算作一次修改,且这个结点不能再被修改。若要将其变成一棵二叉搜索树,且任意时刻结点的数值必须是整数(可以是负整数或0),所要的最少修改次数。

    这一定难不倒聪明的你吧!如果你能帮小L解决这个问题,也许他会把最后的资产分给你1/16哦!

    输入输出格式

    输入格式:

    第一行一个正整数n表示二叉树节点数。

    第二行n个正整数用空格分隔开,第i个数ai表示结点i的原始数值。

    此后n - 1行每行两个非负整数fa, ch,第i + 2行描述结点i + 1的父亲编号fa,以及父子关系ch,(ch = 0 表示i + 1为左儿子,ch = 1表示i + 1为右儿子)。

    为了让你稍微减轻些负担,小L规定:结点1一定是二叉树的根哦!

    输出格式:

    仅一行包含一个整数,表示最少的修改次数

    输入输出样例

    输入样例#1:
    3
    2 2 2
    1 0
    1 1
    输出样例#1:
    2

    说明

    20 % :n <= 10 , ai <= 100.

    40 % :n <= 100 , ai <= 200

    60 % :n <= 2000 .

    100 % :n <= 10 ^ 5 ,  ai < 2 ^ 31. 

    分析:将二叉树中序遍历后求一个最长不降子序列,即保证a[i]-i<=a[j]-j(i<j);

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <map>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <list>
    #define rep(i,m,n) for(i=m;i<=n;i++)
    #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define vi vector<int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define pi acos(-1.0)
    #define pii pair<int,int>
    #define Lson L, mid, rt<<1
    #define Rson mid+1, R, rt<<1|1
    const int maxn=1e5+10;
    using namespace std;
    ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
    ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
    int n,m,k,t,b[maxn][2],a[maxn];
    multiset<int>p;
    multiset<int>::iterator it;
    void add(int x)
    {
        it=p.upper_bound(x);
        if(it!=p.end())p.erase(it);
        p.insert(x);
    }
    void dfs(int now)
    {
        if(b[now][0])dfs(b[now][0]);
        add(a[now]-(++t));
        if(b[now][1])dfs(b[now][1]);
    }
    int main()
    {
        int i,j;
        scanf("%d",&n);
        rep(i,1,n)scanf("%d",&a[i]);
        rep(i,2,n)scanf("%d%d",&j,&k),b[j][k]=i;
        dfs(1);
        printf("%d
    ",n-p.size());
        //system("Pause");
        return 0;
    }
  • 相关阅读:
    Maven关于web.xml中Servlet和Servlet映射的问题
    intellij idea的Maven项目运行报程序包找不到的错误
    修改Maven项目默认JDK版本
    刷题15. 3Sum
    刷题11. Container With Most Water
    刷题10. Regular Expression Matching
    刷题5. Longest Palindromic Substring
    刷题4. Median of Two Sorted Arrays
    刷题3. Longest Substring Without Repeating Characters
    刷题2. Add Two Numbers
  • 原文地址:https://www.cnblogs.com/dyzll/p/5880399.html
Copyright © 2011-2022 走看看