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; }