度序列(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; }