【VK Cup 2016 - Round 1 (Div 2 Edition)C Bear and Forgotten Tree 3 (构造)

来源:互联网 发布:js 拖动 编辑:程序博客网 时间:2024/04/28 22:19
【题意】
让你构造一棵树,使其满足——
1,有n(1e5)个节点
2,树的直径为d
3,距离节点1最远的点的距离为h

【类型】
贪心 构造

【分析】
我们直接从贪心的角度入手做构造就好啦。
只要d>=h>=(d+1)/2即可成功构造
唯一的反例是d==h==1且点数超过2的时候,这个特判一下即可。

构造方法:
首先,我们构造一条长度为d的链,作为这棵树的直径
然后,我们使得节点1这这条链上,距离一端的位置恰好为h

至于剩下的节点,全部连在直径中间的位置即可。


#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<ctype.h>#include<math.h>#include<set>#include<map>#include<vector>#include<queue>#include<bitset>#include<algorithm>#include<time.h>using namespace std;void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }#define MS(x,y) memset(x,y,sizeof(x))#define MC(x,y) memcpy(x,y,sizeof(x))#define MP(x,y) make_pair(x,y)#define ls o<<1#define rs o<<1|1typedef long long LL;typedef unsigned long long UL;typedef unsigned int UI;template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }const int N = 1e5 + 10, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;int n, h, d;int a[N];bool solve(){if (h < (d + 1) / 2)return 0;//必须有h>=(d+1)/2if (h > d)return 0;//必须有h<=dif (n > 2 && d == 1)return 0;//当n>2时必有d>2for (int i = 1; i <= d + 1; ++i)a[i] = i;swap(a[1], a[1 + h]);for (int i = 1; i <= d; ++i)printf("%d %d\n", a[i], a[i + 1]);int p = 1 + d / 2;for (int i = d + 2; i <= n; ++i)printf("%d %d\n", a[p], i);return 1;}int main(){while (~scanf("%d%d%d", &n, &d, &h)){if (!solve())puts("-1");}return 0;}


0 0