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 toi-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
题意:给出无向图所有节点的度组成的集合(集合默认从大到小并且不重复),且无向图中无重边自环,节点数为最高度+1。询问一种构造方式能构造出一个符合上述度集以及要求的图,输出所有的边。保证一定有这样的图存在。
#include<bits/stdc++.h> #define clr(x) memset(x,0,sizeof(x)) #define mod 1000000007 #define clr_1(x) memset(x,-1,sizeof(x)) #define INF 0x3f3f3f3f #define LL long long #define pb push_back #define pbk pop_back using namespace std; const int N=3e3+10; int a[N]; vector<int> dt[N]; int rt,n,p,lt,r,l,ans; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",a+i); for(int i=1;i<=a[n]+1;i++) dt[i].clear(); rt=n; r=a[n]+1; lt=1; l=1; while(lt<=rt) { while(dt[l].size()<a[lt]) { for(int j=l;j<r;j++) dt[j].pb(r); r--; } rt--; lt++; l=a[n]+1-a[rt]; } ans=0; for(int i=1;i<=a[n]+1;i++) ans+=dt[i].size(); printf("%d ",ans); for(int u=1;u<=a[n]+1;u++) { for(auto v:dt[u]) printf("%d %d ",u,v); } return 0; }
//双指针 /* LittleFall : Hello! */ #include <bits/stdc++.h> typedef long long ll; using namespace std; inline int read(); inline void write(int x); const int M = 1024; int save[M]; int main(void) { int n=read(),ans=0; for(int i=1;i<=n;i++) save[i]=read(); int vecs=save[n]+1; int r=n,l=1,ready=0; for(int vec=1;vec<vecs;vec++) { if(save[l]<=ready) l++,r--; else if(ready+vecs-vec==save[r]) ready++,ans+=vecs-vec; } printf("%d ",ans ); r=n,l=1,ready=0; for(int vec=1;vec<vecs;vec++) { if(save[l]<=ready) l++,r--; else if(ready+vecs-vec==save[r]) { for(int j=vec+1;j<=vecs;j++) printf("%d %d ",vec,j ); ready++; ans+=vecs-vec; } } return 0; } inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void write(int x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); }