Educational Codeforces Round 43 D. Degree Set

D. Degree Set
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Input

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.

Output

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.

Examples
input
Copy
3
2 3 4
output
Copy
8
3 1
4 2
4 5
2 5
5 1
3 2
2 1
5 3
input
Copy
3
1 2 3
output
Copy
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.刚好是原问题的一个子问题。
(看到这个官方题解的时候很震撼,分析好久才实现出来,但还是想不到)
 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\n", tot);
75     for (int i = 1; i <= tot; ++i) {
76         printf("%d %d\n", e[i].u, e[i].v);
77     }
78     return 0;
79 }
View Code

 

转载于:https://www.cnblogs.com/BIGTOM/p/8983554.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值