http://codeforces.com/contest/658/problem/C
卧槽。。真是大脑缺氧了。。。这么简单的一个构造题。。。
给你n,d,h构造出一个n个节点 直径为d高为h的树(根为1)
无法构造输出-1;
直接特判【2*h<d】输出-1
还有一个情况就是【h==d的时候,直径是一条链......如果节点n>=d+1的话,那么多出来的节点如果接在根1就会导致直径增加,所以可以接到点2去(这样不会导致直径增加,高度也不变)(注意当d=1的时候还是会导致直径增加,必然-1)】
其余情况直接 先构造一个1-2-3-(h+1)的高,然后补齐1- (h+2)-(h+3)----(d)
然后剩下的点全部和根1直接相连即可。。。。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
__int64 min(__int64 a,__int64 b)
{return a<b?a:b;}
__int64 max(__int64 a,__int64 b)
{return a>b?a:b;}
struct node
{
int x,y;
node(){}
node(int a,int b){x=a,y=b;}
};
node tm[100005];
int cun=0;
int vis[100005];
int main()
{
int i,j;
int n,d,h;
scanf("%d%d%d",&n,&d,&h);
if (h==d)
{
if (n-1>h)
{
if (h==1) {printf("-1\n");return 0;}
int ok=1;
for (i=1;i<=h;i++)
{
printf("%d %d\n",ok,ok+1);
ok++;
}
ok++;
for (i=h+1;i<n;i++)
{
printf("%d %d\n",2,ok);ok++;
}
return 0;
}
}
if (d<h||2*h<d)
{
printf("-1\n");
return 0;
}
int ok=1;
for (i=1;i<=h;i++)
{
//printf("%d %d\n",ok,ok+1);
tm[++cun]=node(ok,ok+1);
ok++;
}
ok++;
int need=d-h;
int flag=0;
if (need)
{
for (i=1;i<=need;i++)
{
if (i==1)
tm[++cun]=node(1,ok);
//printf("1 %d\n",ok);
else
{
//printf("%d %d\n",ok,ok+1);
tm[++cun]=node(ok,ok+1);
ok++;
}
}
ok++;
}
int res=n-d-1;
for (i=1;i<=res;i++)
{
tm[++cun]=node(1,ok);
//printf("1 %d\n",ok);
ok++;
}
if (cun!=n-1)
{
printf("-1\n");
return 0;
}
for (i=1;i<=cun;i++)
{
printf("%d %d\n",tm[i].x,tm[i].y);
}
return 0;
}