原题: http://codeforces.com/problemset/problem/1003/E
题意: 用n个点构造一棵树,每点的度最大为k,直径为d(最长简单路径)
解析:
首先定框架,点1下面,右边是d/2,左边是d-d/2,然后dfs插入即可。注意d的路径点数为d+1。
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define repp(i,b,a) for(int i=b;i>=a;i--)
#define LL long long
#define out {cout<<"NO\n";return 0;}
#define yes {cout<<"YES\n";}
#define pb push_back
const int maxn=4e5+5;
vector<int>Son[maxn];
int ct=0;
int n,d,k;
void In(int p,int dep,int have){
if(ct==n)return;
if(dep==0)return;
rep(i,1,k-have){
Son[p].pb(++ct);
In(ct,dep-1,1);
if(ct==n)return;
}
}
void dfs(int p){
rep(i,0,Son[p].size()-1){
cout<<p<<' '<<Son[p][i]<<endl;
dfs(Son[p][i]);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
//2 1 3
cin>>n>>d>>k;
if(n==1||n<=d)out
if(k==1){
if(n>2)out
else{
if(d!=1)out
else{
yes
cout<<"1 2\n";
return 0;
}
}
}
if(d==1){
if(n!=2)out
else{
yes
cout<<"1 2\n";
return 0;
}
}
//n多
ct++;// p1
ct++;Son[1].pb(2);// p2
ct++;Son[1].pb(3);// p3
int l=d/2,r=l;
if(d%2)l++;
vector<int>Vl,Vr;
for(int now=2,i=1;i<l;i++){
Son[now].pb(++ct);now=ct;
Vl.pb(now);
}
for(int now=3,i=1;i<r;i++){
Son[now].pb(++ct);now=ct;
Vr.pb(now);
}
In(2,l-1,2);
In(3,r-1,2);
rep(i,0,Vl.size()-1)In(Vl[i],l-2-i,2);
rep(i,0,Vr.size()-1)In(Vr[i],r-2-i,2);
int son1=2;
while(ct<n&&son1<k){
son1++;
Son[1].pb(++ct);
In(ct,r-1,1);
}
if(ct<n)out;
yes;
dfs(1);
}