度序列(degree sequence):若把图 G所有顶点的度数排成一个序列 s,则称 s为图 G的度序 列。
序列是可图的(graphic):一个非负整数组成的有限序列如果是某个无向图的度序列,则称 该序列是可图的。判定一个序列是否是可图的,有以下 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个度数(即 d2~dd1+1)减 1 后构成 s1中的前 d1个数。
题目链接:http://poj.org/problem?id=1659
题意:给出一个度序列,判断是否可图,如果可图,输出一种图的情况。
题解:如上定理。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX=15;
struct node
{
int p,d;
node(){};
node(int p,int d):p(p),d(d){};
};
node du[MAX];
int g[MAX][MAX];
bool cmp(node a,node b)
{
return a.d>b.d;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int d;
scanf("%d",&d);
du[i]=node(i,d);
}
memset(g,0,sizeof(g));
int flag=1;
for(int i=0;i<n;i++)
{
sort(du+i,du+n,cmp);
if(du[i].d==0) break;
for(int j=1;j<=du[i].d;j++)
{
if(i+j>=n)
{
flag=0;
break;
}//当前顶点的度数大于所剩点的个数
du[i+j].d--;
if(du[i+j].d<0)//出现负数
{
flag=0;
break;
}
g[du[i].p][du[i+j].p]=g[du[i+j].p][du[i].p]=1;
}
if(flag==0) break;
}
if(flag==0) printf("NO\n");
else
{
printf("YES\n");
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
printf("%d ",g[i][j]);
}
printf("\n");
}
}
if(T)printf("\n");
}
return 0;
}