Havel—Hakimi定理:由非负数组成的非增序列s:d1,d2,···,dn(n>=2,d1>=1)是可图的,当仅当序列
s1:d2-1,d3-1,···,dd1+1 -1,dd1+2,····,dn
是可图的。序列s1中有n-1个非负数,s序列中d1后的前d1个度数减1后构成s1中的前d1个数。
题意:给定一个非负数序列,判断是否可以构成一个图。
根据定理我们可以判断下面两种情形是不合理的。
(1)某次对剩下的序列排序后,最大的度数(设为d1)超过了剩下的顶点数;
(2)对最大度数后面出现d1个度数各减1后,出现了负数。
一旦出现这两种情况则判断为不可图。
#include<iostream>
#include <algorithm>
using namespace std;
const int N=15;
struct vertex
{
int degree;
int index;
}v[N];
int cmp(const void *a,const void *b)
{
return ((vertex*)b)->degree-((vertex*)a)->degree;
}
int main()
{
int r,k,p,q;
int i,j;
int d1;
int T,n;
int Edge[N][N],flag;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&v[i].degree);
v[i].index=i;
}
memset(Edge,0,sizeof(Edge));
flag=1;
for(k=0;k<n&&flag;k++)
{
qsort(v+k,n-k,sizeof(vertex),cmp);
i=v[k].index;
d1=v[k].degree;
if(d1>n-k-1)flag=0;
for(r=1;r<=d1&&flag;r++)
{
j=v[k+r].index;
if(v[k+r].degree<=0)flag=0;
v[k+r].degree--;
Edge[i][j]=Edge[j][i]=1;
}
}
if(flag)
{
printf("YES\n");
for(p=0;p<n;p++)
{
for(q=0;q<n;q++)
{
if(q)printf(" ");
printf("%d",Edge[p][q]);
}
printf("\n");
}
}else printf("NO\n");
if(T)printf("\n");
}
return 0;
}