题目链接:https://codeforces.com/problemset/problem/658/C
思路:先构造深度为h的链,再在这个基础上构造直径为d的链,最后所有的点都把它连到深度为h-1的那个节点上,这样可以保证直径不超过d同时树的深度不会超过h
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<cmath>
#include<stack>
#include<map>
#include<set>
using namespace std;
#define LL long long
const int mod=1000000007;
const int inf=0x3f3f3f3f;
const LL inff=0x3f3f3f3f3f3f3f3f;
const LL N=100005;
const LL M=5;
#define MEF(x) memset(x,-1,sizeof(x))
#define ME0(x) memset(x,0,sizeof(x))
#define MEI(x) memset(x,inf,sizeof(x))
struct Edge
{
int l,r;
}edge[N];
int main()
{
int n,d,k;
scanf("%d%d%d",&n,&d,&k);
if(d>k*2||(d==1&&n>2))
{
printf("-1\n");
}
else
{
int st=1,len=0;
for(int i=1;i<=k&&st<n;i++)
{
edge[len].l=st;
edge[len++].r=st+1;
st++;
}
for(int i=1;i<=d-k&&st<n;i++)
{
if(i==1)
{
edge[len].l=1;
edge[len++].r=st+1;
st++;
}
else
{
edge[len].l=st;
edge[len++].r=st+1;
st++;
}
}
for(int i=st+1;i<=n;i++)
{
edge[len].l=k;
edge[len++].r=i;
}
for(int i=0;i<len;i++)
{
printf("%d %d\n",edge[i].l,edge[i].r);
}
}
return 0;
}