题意:
构造一个无向图,使得无向图里的所有点的度数 所组成的集合 即为给出的几个数
解析:
题中的数是以上升的顺序给出的,
我们对于dn+1个数进行处理,对于当前数i,有两个操作
1、向后边的所有点连边 称为主动连边
2、跳过该数 即不向后边的点连边,称为被动连边
设tot = dn+1, l = 1, r = n,ready 为对于当前点i前面的主动连边的点的数量
如果ready + tot - i == d[r] (即前面的点向它连的边 加上 当前点向后边的点连的边(即为总点数减去当前点的下标(下标从1开始))等于d[r])
那就ready++,即把当前点和后边的点连边
如果ready == d[l] 说明当前点前面的点 向后连的边 等于d[l] 即当前点不向后边主动连边
那就l++, r--; //因为如果要符合这个判断 肯定符合上一个判断 因为只有符合上一个判断的时候ready才会++ 才会加到
#include <bits/stdc++.h> #define mem(a, b) memset(a, b, sizeof(a)) using namespace std; const int maxn = 1e6+10, INF = 0x7fffffff; typedef long long LL; int n; int d[maxn]; vector<int> G[maxn]; int tot; void build(int u) { for(int i=u+1; i<=tot; i++) G[u].push_back(i); } int main() { cin>> n; for(int i=1; i<=n; i++) { cin>> d[i]; } tot = d[n] + 1; int l = 1, r = n, ready = 0; LL ans = 0; for(int i=1; i<=tot; i++) { if(ready == d[l]) l++, r--; else if(ready + tot - i == d[r]) ready++, build(i), ans += tot - i; //同时ans 记录一共有几条边 } cout<< ans <<endl; for(int i=1; i<=tot; i++) for(int j=0; j<G[i].size(); j++) cout << i << " " << G[i][j] <<endl; return 0; }