You are given a sequence of n positive integers d1, d2, ..., dn (d1 < d2 < ... < dn). Your task is to construct an undirected graph such that:
- there are exactly dn + 1 vertices;
- there are no self-loops;
- there are no multiple edges;
- there are no more than 106 edges;
- its degree set is equal to d.
Vertices should be numbered 1 through (dn + 1).
Degree sequence is an array a with length equal to the number of vertices in a graph such that ai is the number of vertices adjacent to i-th vertex.
Degree set is a sorted in increasing order sequence of all distinct values from the degree sequence.
It is guaranteed that there exists such a graph that all the conditions hold, and it contains no more than 106 edges.
Print the resulting graph.
The first line contains one integer n (1 ≤ n ≤ 300) — the size of the degree set.
The second line contains n integers d1, d2, ..., dn (1 ≤ di ≤ 1000, d1 < d2 < ... < dn) — the degree set.
In the first line print one integer m (1 ≤ m ≤ 106) — the number of edges in the resulting graph. It is guaranteed that there exists such a graph that all the conditions hold and it contains no more than 106 edges.
Each of the next m lines should contain two integers vi and ui (1 ≤ vi, ui ≤ dn + 1) — the description of the i-th edge.
3
2 3 4
8
3 1
4 2
4 5
2 5
5 1
3 2
2 1
5 3
3
1 2 3
4
1 2
1 3
1 4
2 3
思路:对于当前度序列(d1, d2, d3, ..., d(k - 1), dk)且总点数为dk + 1,我们取d1个点连接所有的点,取dk - dk - 1个点只连之前这d1个点。此时问题变为d1个度为dk的点,dk - dk -1个度为d1的点,以及待处理度序列
(d2 - d1, d3 - d1, ..., d(k - 1) - d1),且总点数为dk + 1 - d1 - (dk - d(k - 1)) = d(k - 1) - d1 + 1.刚好是原问题的一个子问题。
(看到这个官方题解的时候很震撼,分析好久才实现出来,但还是想不到)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <cmath> 7 #include <string> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <stack> 12 #include <vector> 13 #include <set> 14 #include <map> 15 #include <list> 16 #include <iomanip> 17 #include <cctype> 18 #include <cassert> 19 #include <bitset> 20 #include <ctime> 21 22 using namespace std; 23 24 #define pau system("pause") 25 #define ll long long 26 #define pii pair<int, int> 27 #define pb push_back 28 #define mp make_pair 29 #define clr(a, x) memset(a, x, sizeof(a)) 30 31 const double pi = acos(-1.0); 32 const int INF = 0x3f3f3f3f; 33 const int MOD = 1e9 + 7; 34 const double EPS = 1e-9; 35 36 /* 37 #include <ext/pb_ds/assoc_container.hpp> 38 #include <ext/pb_ds/tree_policy.hpp> 39 40 using namespace __gnu_pbds; 41 tree<pli, null_type, greater<pli>, rb_tree_tag, tree_order_statistics_node_update> T; 42 */ 43 44 int n, d[305]; 45 int p[1015]; 46 struct edge { 47 int u, v; 48 edge () {} 49 edge (int u, int v) : u(u), v(v) {} 50 } e[1000015]; 51 int tot, nex[1000015], head[1015]; 52 void addEdge(int u, int v) { 53 e[++tot] = edge(u, v), nex[tot] = head[u], head[u] = tot; 54 } 55 int main() { 56 scanf("%d", &n); 57 for (int i = 1; i <= n; ++i) { 58 scanf("%d", &d[i]); 59 } 60 for (int i = 1, index2 = d[n] + 1, index1 = 1; i <= n; ++i) { 61 if (!d[i]) continue; 62 for (int j = index2; j > index2 - d[i]; --j) { 63 for (int k = j - 1; k >= index1; --k) { 64 addEdge(j, k); 65 } 66 } 67 index2 -= d[i]; 68 index1 += d[n] - d[n - 1]; 69 --n; 70 for (int j = i + 1; j <= n; ++j) { 71 d[j] -= d[i]; 72 } 73 } 74 printf("%d ", tot); 75 for (int i = 1; i <= tot; ++i) { 76 printf("%d %d ", e[i].u, e[i].v); 77 } 78 return 0; 79 }