题目链接:http://codeforces.com/problemset/problem/657/A
A tree is a connected undirected graph consisting of n vertices and n - 1 edges. Vertices are numbered 1 through n.
Limak is a little polar bear and Radewoosh is his evil enemy. Limak once had a tree but Radewoosh stolen it. Bear is very sad now because he doesn't remember much about the tree — he can tell you only three values n, d and h:
The distance between two vertices of the tree is the number of edges on the simple path between them.
Help Limak to restore his tree. Check whether there exists a tree satisfying the given conditions. Find any such tree and print its edges in any order. It's also possible that Limak made a mistake and there is no suitable tree – in this case print "-1".
The first line contains three integers n, d and h (2 ≤ n ≤ 100 000, 1 ≤ h ≤ d ≤ n - 1) — the number of vertices, diameter, and height after rooting in vertex 1, respectively.
If there is no tree matching what Limak remembers, print the only line with "-1" (without the quotes).
Otherwise, describe any tree matching Limak's description. Print n - 1 lines, each with two space-separated integers – indices of vertices connected by an edge. If there are many valid trees, print any of them. You can print edges in any order.
5 3 2
1 2
1 3
3 4
3 5
8 5 2
-1
8 4 2
4 8
5 7
2 3
8 1
2 1
5 6
1 5
思路:结果不唯一,构造算法。我的构造过程是,先按深度一个一个节点构造,再按直径一个一个节点构造,最后将剩下的节点放在一个节点上即可。注意几种特殊情况,一种是高和直径为1,而节点数不为2;另一种是高和直径相同。
直接附上AC代码:
#include <bits/stdc++.h> using namespace std; int n, d, h; int main(){ #ifdef LOCAL //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); #endif ios::sync_with_stdio(false); cin.tie(0); cin >> n >> d >> h; if (2*h<d || d<h)<span style="white-space:pre"> </span>// 满足此条件,显然不可能 cout << "-1" << endl; else if (n == 2){ if (d == 1) cout << "1 2" << endl; else cout << "-1" << endl; } else if (d == h){ if (n != 2 && d==1 && h==1){<span style="white-space:pre"> </span>// 节点数太多,不科学 cout << "-1" << endl; return 0; } for (int i=1; i<=d; ++i) cout << i << " " << i+1 << endl; for (int i=d+2; i<=n; ++i)<span style="white-space:pre"> </span>// 高度和直径一样,换个节点构造 cout << "2 " << i << endl; } else{ for (int i=1; i<=h; ++i)<span style="white-space:pre"> </span>// 构造高度 cout << i << " " << i+1 << endl; int cnt = h+2; if (h < n-1) cout << "1 " << cnt << endl; for (int i=0; i<d-h-1; ++i, ++cnt)<span style="white-space:pre"> </span>// 构造直径 cout << cnt << " " << cnt+1 << endl; cnt += 1; for (int i=0; i<n-1-d; ++i, ++cnt)<span style="white-space:pre"> </span>// 构造剩余节点 cout << "1 " << cnt << endl; } return 0; }