CF 1003 E Tree Constructing【构造】

CF 1003 E

E. Tree Constructing
time limit per test4 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given three integers
n
n,
d
d and
k
k.

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

An undirected tree is a connected undirected graph with
n

1
n−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
u
u it is the number of edges
(
u
,
v
)
(u,v) that belong to the tree, where
v
v is any other vertex of a tree).

Input
The first line of the input contains three integers
n
n,
d
d and
k
k (
1

n
,
d
,
k

4

10
5
1≤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

1
n−1 lines describing edges of a tree satisfying the conditions above. Vertices of the tree must be numbered from
1
1 to
n
n. You can print edges and vertices connected by an edge in any order. If there are multiple answers, print any of them.1

Examples
inputCopy
6 3 3
outputCopy
YES
3 1
4 1
1 2
5 2
2 6
inputCopy
6 2 3
outputCopy
NO
inputCopy
10 4 3
outputCopy
YES
2 9
2 10
10 3
3 1
6 10
8 2
4 3
5 6
6 7
inputCopy
8 5 3
outputCopy
YES
2 5
7 2
3 7
3 1
1 6
8 7
4 3

题意:题目给出两个限制条件的d,k。想让构造出一个两节点最远距离为d,每个节点度数不超过k的树。

扫描二维码关注公众号,回复: 2356157 查看本文章

构造方法有很多,我是从根节点开始构造的。
1、度数是非常好构造的,除了根节点,其余的节点儿子不超过k-1即可(另一度连着其父亲)。
2、如果构造出来的树(视作图)尽可能的中心对称,那么他的两节点最远距离肯定最小(毕竟能放儿子的地方都放上了)。所以可以通过最远距离的奇偶进行分类讨论。

如果最远距离是偶数,那么直接以根节点中心对称构造好了。

如果最远距离是奇数,那么取一条边放在中间,左右以此边为中心,对称构造就好了。

画画图就了然了

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
int n,d,k,x;
vector <int>v1,v2;
void add(int u,int v){
    v1.push_back(u);
    v2.push_back(v);
}
void dfs(int u,int du,int cs){
    if(cs){
        while(du--){
            if(x>=n) return;
            x++;
            add(u,x);
            dfs(x,k-1,cs-1);
        }
    }
}
int main()
{
    scanf("%d %d %d",&n,&d,&k);x=1;
    if(n==1||d>=n) {puts("NO");return 0;}
    int dd=d/2;
    if(d%2==1){
        int tmp=n/2-1;
        add(1,2);x=2;n-=tmp;
        dfs(1,k-1,dd);n+=tmp;
        dfs(2,k-1,dd);
    }
    else{
        int tmp=n/2;
        n-=tmp;dfs(1,k/2,dd);
        n+=tmp;dfs(1,k-k/2,dd);
    }
    if(x<n) {puts("NO");return 0;}
    puts("YES");
    for(int i=0;i<n-1;i++){
        printf("%d %d\n",v1[i],v2[i]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/irish_moonshine/article/details/80968771