【题解】CF746G New Roads

CF746G New Roads

题意

​ 给你一棵 t t t层的树,第 i i i层有 a [ i ] a[i] a[i]个节点,最后需要有 k k k个叶子结点,让你构造出一棵符合条件的树。

解题思路

​ 我们可以先构造出 t t t层,每层只有一个节点,父亲是上一层的节点。那么显然此时剩余的节点数为 n − t n-t nt。剩余所需的非叶子节点的数量为 n − t − k n-t-k ntk。于是我们可以逐层插入节点,并对这些节点分类讨论。设此时已经插入到第 i i i层的第 j j j个点。如果此时还需要非叶子节点,那么它的父亲就可以是第 i − 1 i-1 i1层的第 j j j个,这样它的父亲就变为了非叶子节点;反之,如果不需要非叶子节点,直接用上一层的第一个节点当做它的父亲,那么上一层当前位置的节点就成为了叶子结点。

​ 对于无解的判断,无非就是最末层的节点数大于 k k k,因为最后一层的节点必定是叶子结点。或者在构造完之后还需要非叶子节点,但此时已经没有可以构造的叶子节点了。

代码

#include <bits/stdc++.h>
using namespace std;

int n, t, k, cnt;
vector<int> v[200005];
int a[200005], fa[200005];

int main()
{
    cin >> n >> t >> k;
    a[0] = 1;
    for(int i = 1; i <= t; i++){
        scanf("%d", &a[i]);
    }
    if(a[t]>k || n-t<k){
        puts("-1");
        return 0;
    }
    for(int i = 0; i <= t; i++){
        for(int j = 1; j <= a[i]; j++)
            v[i].push_back(++cnt);
    }
    for(int i = 0; i < a[1]; i++){
        fa[v[1][i]] = 1;
    }
    for(int i = 2; i <= t; i++){
        fa[v[i][0]] = v[i-1][0];
    }
    int l = n-t-k;
    for(int i = 2; i <= t; i++){
        for(int j = 1; j < a[i]; j++){
            if(l && j < a[i-1]){
                fa[v[i][j]] = v[i-1][j];
                l--;
            }
            else{
                fa[v[i][j]] = v[i-1][0];
            }
        }
    }
    if(l){
        puts("-1");
        return 0;
    }
    cout << n << endl;
    for(int i = 2; i <= n; i++){
        printf("%d %d\n", fa[i], i);
    }
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值