• 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;
    }
    
  • 相关阅读:
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & ManacherK
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher J
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher I
    pat 1065 A+B and C (64bit)(20 分)(大数, Java)
    pat 1069 The Black Hole of Numbers(20 分)
    pat 1077 Kuchiguse(20 分) (字典树)
    pat 1084 Broken Keyboard(20 分)
    pat 1092 To Buy or Not to Buy(20 分)
    pat 1046 Shortest Distance(20 分) (线段树)
    pat 1042 Shuffling Machine(20 分)
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13968500.html
Copyright © 2020-2023  润新知