当
n=0
n
=
0
,只需一个点即可。
当
n=1
n
=
1
,构造一个
d1+1
d
1
+
1
个点的完全图即可。
那么对于原问题要求构造度数集合为
{d1,d2,...,dn−1,dn}
{
d
1
,
d
2
,
.
.
.
,
d
n
−
1
,
d
n
}
的一个图,可以从所有
dn+1
d
n
+
1
个点中拿出
d1
d
1
个点,向其它所有点连边,就满足了集合中
d1
d
1
和
dn
d
n
的要求。然后去掉这
d1
d
1
个点,再去掉其他点中的
dn−dn−1
d
n
−
d
n
−
1
个点,就变成了一个有
dn−1−d1+1
d
n
−
1
−
d
1
+
1
个点,要求构造
{d2−d1,d3−d1,...dn−1−d1}
{
d
2
−
d
1
,
d
3
−
d
1
,
.
.
.
d
n
−
1
−
d
1
}
的一个图,也就变成了一个子问题。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define pii pair<int,int>
#define fs first
#define sc second
#define MP make_pair
using namespace std;
int n,d[310],m;
pii e[1000010];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&d[i]);
int L=1,R=d[n]+1;
for(int i=1,j=n;i<=n/2;i++,j--)
{
for(int k=0;k<d[i];k++)
for(int l=L;l<R-k;l++)
e[++m]=MP(R-k,l);
L+=d[j]-d[j-1];R-=d[i];
for(int k=i+1;k<j;k++)
d[k]-=d[i];
}
if(n&1)
for(int i=L;i<=R;i++)
for(int j=L;j<i;j++)
e[++m]=MP(i,j);
printf("%d\n",m);
for(int i=1;i<=m;i++)
printf("%d %d\n",e[i].fs,e[i].sc);
return 0;
}