• [Codeforces 1286B] Numbers on Tree | 技巧构造


    Evlampiy was gifted a rooted tree. The vertices of the tree are numbered from 1 to n. Each of its vertices also has an integer ai written on it. For each vertex i, Evlampiy calculated ci — the number of vertices j in the subtree of vertex i, such that a j < a i aj<ai aj<ai
    在这里插入图片描述
    Illustration for the second example, the first integer is ai and the integer in parentheses is ci
    After the new year, Evlampiy could not remember what his gift was! He remembers the tree and the values of ci, but he completely forgot which integers ai were written on the vertices.

    Help him to restore initial integers!

    Input
    The first line contains an integer n ( 1 ≤ n ≤ 2000 ) (1≤n≤2000) (1n2000) — the number of vertices in the tree.

    The next n lines contain descriptions of vertices: the i-th line contains two integers pi and c i ( 0 ≤ p i ≤ n ; 0 ≤ c i ≤ n − 1 ) ci (0≤p_i≤n; 0≤c_i≤n−1) ci(0pin;0cin1), where pi is the parent of vertex i or 0 if vertex i is root, and ci is the number of vertices j in the subtree of vertex i, such that aj<ai.

    It is guaranteed that the values of pi describe a rooted tree with n vertices.

    Output
    If a solution exists, in the first line print “YES”, and in the second line output n integers ai ( 1 ≤ a i ≤ 1 0 9 ) (1≤a_i≤10^9) (1ai109). If there are several solutions, output any of them. One can prove that if there is a solution, then there is also a solution in which all ai are between 1 and 1 0 9 10^9 109.

    If there are no solutions, print “NO”.

    Examples
    inputCopy

    3
    2 0
    0 2
    2 0
    

    outputCopy

    YES
    1 2 1 
    

    inputCopy

    5
    0 1
    1 3
    2 1
    3 0
    2 0
    

    outputCopy

    YES
    2 3 2 1 2
    

    题意:

    一刻n个点的有根树,每个节点有一个值 a i a_i ai
    给出每个结点的祖先 f a fa fa f a fa fa为0代表这个点为根节点),以及子节点中 a j < a i a_j < a_i aj<ai的点的个数 c i c_i ci
    需要构造的就是 a a a数组的值

    对于需要构造的n个数,我们可以将其设为从1~n里面的数,而且为了消除相同的影响并方便构造,两两之间 a a a值不同
    第一步我们可以找到每个节点为根的情况下,他的子树的结点的数量是多少通过dfs即可获得
    对于一个点,如果他的 c i c_i ci甚至大于了他的子树中结点的个数,那么说这种就是不可能的情况,应该输出NO
    其余的情况,一定是有一种解的
    怎样构造出 a i a_i ai
    首先我们可以用dfs的方式在对一个点 u u u进行操作的时候,我们求出所有没有被访问过的节点中的第 c [ u ] + 1 c[u]+1 c[u]+1个点 i i i,那么说就可以想象到 a [ u ] = i a[u] = i a[u]=i,然后继续dfs所连边即可

    Code:

    int n;
    struct node{
    	int to,nex;
    }e[maxn];
    int cnt,head[maxn];
    void init(){
    	cnt = 0;
    	for(int i=1;i<=n;i++) head[i] = -1;
    }
    void add(int u,int v){
    	e[cnt].to = v;
    	e[cnt].nex = head[u];
    	head[u] = cnt ++;
    }
    int root;
    int fa,c[maxn];
    int siz[maxn],a[maxn];
    bool vis[maxn];
    void dfs(int u) {
    	int cnt = 0;
    	for(int i=1;i<=n;i++){
    		if(vis[i]) continue;
    		cnt ++;
    		if(cnt == c[u] + 1) {
    			vis[i] = 1;
    			a[u] = i;
    			break;
    		}
    	}
    	for(int i=head[u];~i;i=e[i].nex) {
    		int to = e[i].to;
    		dfs(to);
    	}
    }
    void get(int u) {
    	siz[u] = 1;
    	for(int i=head[u];~i;i=e[i].nex) {
    		int to = e[i].to;
    		get(to);
    		siz[u] += siz[to];
    	}
    }
    int main() {
    	n = read;
    	init();
    	for(int i=1;i<=n;i++) {
    		fa = read,c[i] = read;
    		if(fa == 0) {
    			root = i;
    			continue;
    		}
    		add(fa,i);
    	}
    	get(root);
    	for(int i=1;i<=n;i++){
    		if(c[i] >= siz[i]) {
    			puts("NO");
    			return 0;
    		}
    	}
    	puts("YES");
    	dfs(root);/// root vet
    	for(int i=1;i<=n;i++){
    		printf("%d ",a[i]);
    	}
    	return 0;
    }
    /**
    
    
    **/
    
  • 相关阅读:
    RabbitMQ学习之集群消息可靠性测试
    RabbitMQ学习之集群镜像模式配置
    (转)RabbitMQ学习之集群部署
    RabbitMQ学习之集群模式
    RabbitMQ学习之spring配置文件rabbit标签的使用
    RabbitMQ学习之messageconver插件实现(Gson)
    RabbitMQ学习之基于spring-rabbitmq的RPC远程调用
    RabbitMQ学习之基于spring-rabbitmq的消息异步发送
    (转)RabbitMQ学习之spring整合发送异步消息(注解实现)
    范仁义js课程---16、非bool值的逻辑运算
  • 原文地址:https://www.cnblogs.com/PushyTao/p/16196745.html
Copyright © 2020-2023  润新知