序列是可图的:一个非负整数组成的有限序列如果是某个无向图的度序列,则称该序列是可图的。
判定一个序列是否是可图的,有以下Havel-Hakimi定理。
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)对当前数列排序,使其呈递减
(2)从S【2】开始对其后S【1】个数字-1
(3)一直循环直到当前序列出现负数或者最大度数超过了剩下的顶点数(即不是可图的情况)、当前序列全为0 (可图)时退出
Havel-Hakimi定理说简单点就是给你每个顶点的度数,看它们能不能构成图。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Elem
{
int num,cou;
};
bool cmp (Elem a,Elem b)
{
return a.cou>b.cou;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
Elem p[15];
scanf("%d",&n);
for(int i=1; i<=n; ++i)
{
scanf("%d",&p[i].cou);
p[i].num=i;
}
int Mat[12][12]= {0};
int pos=1;
sort(p+1,p+n+1,cmp);
bool ok=true;
while(p[pos].cou&&ok)
{
if(p[pos].cou>n-pos)
{
ok=false;
break;
}
else
{
for(int i=1; i<=p[pos].cou&&ok; ++i)
{
p[pos+i].cou--;
if(p[pos+i].cou<0)
{
ok=false;
break;
}
int x=p[pos].num,y=p[pos+i].num;
Mat[x][y]=Mat[y][x]=1;
}
pos++;
if(ok) sort(p+pos,p+n+1,cmp);
}
}
if(!ok)
printf("NO\n");
else
{
printf("YES\n");
for(int i=1; i<=n; ++i)
{
for(int j=1; j<=n; ++j)
if(j==1) printf("%d",Mat[i][j]);
else printf(" %d",Mat[i][j]);
printf("\n");
}
}
if(T)printf("\n");
}
return 0;
}