Educational Codeforces Round 43 (Rated for Div. 2) D. Degree Set

本文介绍了一种算法,该算法能够根据给定的递增正整数序列(度数集),构造一个无向图。确保图中不存在自环或多条边,并且总的边数不超过106。同时,文章提供了完整的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 ≤ 1000d1 < 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.

#include<bits/stdc++.h>
using namespace std;
const int maxn=303;
int a[maxn],tol,last,cnt;
stack<int>P,Q;
void add(int x)
{
    for(int i=x+1;i<=tol;i++)
    {
        P.push(x);
        Q.push(i);
    }
}
int main()
{
    int n;scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    tol=a[n]+1,last=0,cnt=0;
    int i,l,r;
    for(i=1,l=1,r=n;i<=tol&&l<=r;i++)
    {
        if(cnt+tol-i==a[r])
        {
            cnt++;r--;
            add(i);last=1;
        }
        else if(cnt==a[l]) l++,last=0;
        else if(last) cnt++,add(i);
    }
    if(last)
    {
        for( ;i<=tol;i++)add(i);
    }
    int T=Q.size();
    printf("%d\n",T);
    while(T--)
    {
        printf("%d %d\n",P.top(),Q.top());
        P.pop();Q.pop();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值