zoukankan      html  css  js  c++  java
  • CF1311E Construct the Binary Tree

    CF1311E Construct the Binary Tree

    洛谷传送门

    题目描述

    You are given two integers nn and dd . You need to construct a rooted binary tree consisting of nn vertices with a root at the vertex 11 and the sum of depths of all vertices equals to dd .

    A tree is a connected graph without cycles. A rooted tree has a special vertex called the root. A parent of a vertex vv is the last different from vv vertex on the path from the root to the vertex vv . The depth of the vertex vv is the length of the path from the root to the vertex vv . Children of vertex vv are all vertices for which vv is the parent. The binary tree is such a tree that no vertex has more than 22 children.

    You have to answer tt independent test cases.

    输入格式

    The first line of the input contains one integer tt ( 1 le t le 10001≤t≤1000 ) — the number of test cases.

    The only line of each test case contains two integers nn and dd ( 2 le n, d le 50002≤n,d≤5000 ) — the number of vertices in the tree and the required sum of depths of all vertices.

    It is guaranteed that the sum of nn and the sum of dd both does not exceed 50005000 ( sum n le 5000, sum d le 5000∑n≤5000,∑d≤5000 ).

    输出格式

    For each test case, print the answer.

    If it is impossible to construct such a tree, print "NO" (without quotes) in the first line. Otherwise, print "{YES}" in the first line. Then print n-1n−1 integers p_2, p_3, dots, p_np2,p3,…,p**n in the second line, where p_ip**i is the parent of the vertex ii . Note that the sequence of parents you print should describe some binary tree.

    题意翻译

    要求构造一个n个节点的二叉树(每个节点拥有不超过2个孩子),节点1为根,要使所有节点到根的距离之和为d。要求先判断可不可以构造,如果可以输出“YES”,下一行输出2到n号节点的父亲节点,否则输出“NO”。有多组询问。


    题解:

    与其说是树题,还不如说是模拟题。

    很容易判断上下界:上界就是链,下界就是完全二叉树。

    构造的话,先构造一棵完全二叉树,然后拎出来一条链(最长链),从后往前(因为是按编号构造的初始树)依次尝试把当前节点链到下一层。这样,深度就会逐一递增。所以一定会有合法解。

    只需要模拟这个过程就行。

    说着容易,看代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=5005;
    int t,n,d,tot;
    int fa[maxn],deep[maxn],chain[maxn];
    bool v[maxn];
    void clear()
    {
    	tot=0;
    	memset(v,0,sizeof(v));
    	chain[0]=1;
    }
    int main()
    {
    	scanf("%d",&t);
    	while(t--)
    	{
    		clear();
    		scanf("%d%d",&n,&d);
    		for(int i=2;i<=n;i++)
    		{
    			fa[i]=i/2;
    			deep[i]=deep[fa[i]]+1;
    			d-=deep[i];
    			tot=max(tot,deep[i]);
    		}
    		if(d<0)
    		{
    			puts("NO");
    			continue;
    		}
    		int p=n;
    		while(p)
    		{
    			chain[deep[p]]=p;
    			v[p]=1;
    			p=fa[p];
    		}
    		for(int i=n;i>=1;i--)
    		{
    			if(v[i])
    				continue;
    			int mx=tot;
    			while(deep[fa[i]]<mx && d)
    			{
    				fa[i]=chain[deep[fa[i]]+1],deep[i]=deep[fa[i]]+1;
    				if(deep[i]>tot)
    					chain[++tot]=i,v[i]=1;
    				d--;
    			}
    		}
    		if(d)
    		{
    			puts("NO");
    			continue;
    		}
    		puts("YES");
    		for(int i=2;i<=n;i++)
    			printf("%d ",fa[i]);
    		puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    屠呦呦团队研究新进展:青蒿中有其他抗疟成分
    lammps模拟化学反应(1)
    伪类的使用--鼠标悬浮效果
    bootstrap中模态框的使用
    idea_2018.1.5版本的激活使用
    火狐浏览器开发者版本
    使用bootstrap的相关配置
    StringBuffer类
    如何判断字符串中大写字母,小写字母和数字出现的次数??
    ssm框架结构的搭建
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13968500.html
Copyright © 2011-2022 走看看