• 洛谷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;
    }
  • 相关阅读:
    Java基础101 给c:forEach的select下拉框中的值,设置默认值(后台传值,前台默认选中)
    Java进阶知识27 SSH整合(Struts2、Spring、Hibernate)
    错误/异常:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/classes/beans_common.xml]...的解决方法
    Java进阶知识26 Spring与Hibernate整合到一起
    Java进阶知识25 Spring的事务管理(事务回滚)
    spring各个版本源码
    sql之left join、right join、inner join的区别
    git命令之git stash 暂存临时代码
    apollo配置相关
    idea快捷键
  • 原文地址:https://www.cnblogs.com/dyzll/p/5880399.html
Copyright © 2020-2023  润新知