Code-force 1003 E Tree Constructing

Posted zgqblogs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Code-force 1003 E Tree Constructing相关的知识,希望对你有一定的参考价值。

                                                                                                E. Tree Constructing

You are given three integers nn, dd and kk.

Your task is to construct an undirected tree on nn vertices with diameter dd and degree of each vertex at most kk, or say that it is impossible.

An undirected tree is a connected undirected graph with n?1n?1 edges.

Diameter of a tree is the maximum length of a simple path (a path in which each vertex appears at most once) between all pairs of vertices of this tree.

Degree of a vertex is the number of edges incident to this vertex (i.e. for a vertex uu it is the number of edges (u,v)(u,v) that belong to the tree, where vv is any other vertex of a tree).

Input

The first line of the input contains three integers nn, dd and kk (1n,d,k4?1051≤n,d,k≤4?105).

Output

If there is no tree satisfying the conditions above, print only one word "NO" (without quotes).

Otherwise in the first line print "YES" (without quotes), and then print n?1n?1 lines describing edges of a tree satisfying the conditions above. Vertices of the tree must be numbered from 11 to nn. You can print edges and vertices connected by an edge in any order. If there are multiple answers, print any of them.1

 

题意:

  要构建一颗树,树的直径要是d,就是树上的节点最远的距离为d,每个节点的度最多为k,一共有n个节点。

思路:

  先判断可不可以建出符合要求的树,可以的话,先把直径建好,再到这条直径上挂上子树。

  技术分享图片

 

  注意子树的深度变化,还有建树的过程中,并不一定是建的如此之满,所以当节点数用完时,要及时退出。

AC代码(C++)

#include<iostream>
#include<queue>
using namespace std;
int n,d,k,flag,t;
int quick_pow(int a,int b)
{
    int ans=0,t=1;
    for(int i=0;i<b;i++){
        t*=a;
        ans+=t;
        if(ans>=n){return -1;}
    }
    return ans;
}

void build(int s,int h,int de)//de是子树的深度,s是父节点
{
    if(h>de){return;}
    if(t>=n){return;}
    t++;
    printf("%d %d
",s,t);
    if(t>=n){return;}
    int o=t;
    if(h>de-1){return;}
    for(int i=0;i<k-1;i++){
        build(o,h+1,de);
        if(t>=n){return;}
    }
}

int main()
{
    scanf("%d%d%d",&n,&d,&k);
    if(n<d+1){printf("NO");return 0;}
    if(d&1){
        t=quick_pow(k-1,d/2);
        if(t==-1){printf("YES
");}
        else{
            t=2*(t+1);
            if(t<n){printf("NO");return 0;}
        }
    }
    else {
        t=quick_pow(k-1,d/2-1);
        if(t==-1){printf("YES
");}
        else{
            t=k*t+1+k;
            if(t<n){printf("NO");return 0;}
        }
    }
    if(t!=-1){printf("YES
");}
    int de=-1;
    t=d+1;
    for(int i=1;i<=d;i++){
        printf("%d %d
",i,i+1);
        if(t>=n){continue;}
        if(d&1){
            if(i<=d/2+1){de++;}
            else if(i>d/2+2){de--;}
        }
        else {
            if(i<=d/2+1){de++;}
            else de--;
        }
        for(int j=0;j<k-2;j++){
            build(i,1,de);if(t>=n){break;}
        }
    }
}

  

 


以上是关于Code-force 1003 E Tree Constructing的主要内容,如果未能解决你的问题,请参考以下文章

使用 SQL 。从字符串'HEADER|N1000|E1001|N1002|E1003|N1004|N1005'中提取逗号分隔的数字

HDU 1003 最大子段和

poj 1003(C++)

2017百度之星资格赛 1003:度度熊与邪恶大魔王(DP)

1003: [ZJOI2006]物流运输

CodeForces - 1003D