给定一个非负整数列,判断其是否是可图的;
(Havel-Hakimi定理) 由非负整数组成的非增序列s:d1, d2, …, dn(n ≥2, d1 ≥1)
是可图的,当且仅当序列
s1: d2– 1, d3– 1, …, d(d1+1)– 1, d(d1+2), …, dn
是可图的。序列s1中有n-1个非负整数,s序列中d1后的前d1个度数(即d2~d(d1+1))减1后构成s1中的前d1个数;
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 15;
struct vertex{
int degree;
int numvertex;
}V[N];
int cmp(const void *a, const void *b)
{
vertex *aa = (vertex *)a;
vertex *bb = (vertex *)b;
return aa->degree < bb->degree;
}
int main()
{
int i;
bool flag;
int Edge[N][N];
int T;
int n, d1;
cin>>T;
while( T-- )
{
cin>>n;
for(i = 0; i < n; ++i)
{
cin>>V[i].degree;
V[i].numvertex = i;
}
memset(Edge, 0, sizeof(Edge));
flag = true;
for(int k = 0; k < n && flag; ++k)
{
qsort(V + k, n - k, sizeof(vertex), cmp);
i = V[k].numvertex;
d1 = V[k].degree;
if(d1 > n - k - 1)
flag = false;
for(int j = 1; j <= d1 && flag; ++j)
{
int r;
r = V[j + k].numvertex;
if( V[j + k].degree <= 0 )
flag = false;
V[ j + k ].degree--;
Edge[i][r] = Edge[r][i] = 1;
}
}
if(flag)
{
cout<<"YES"<<endl;
for(int p = 0; p < n; ++p)
{
for(int q = 0; q < n; ++q)
{
if(q)
cout<<" ";
cout<<Edge[p][q];
}
cout<<endl;
}
}
else
cout<<"NO"<<endl;
if(T)
cout<<endl;
}
return 0;
}
或
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define 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; //对剩下序列排序后第1个顶点(度数最大的顶点)的度数
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++ )
{
//对v数组后n-k个元素按非递增顺序排序
qsort( v+k, n-k, sizeof(vertex), cmp );
i = v[k].index; //第k个顶点的序号
d1 = v[k].degree;
if( d1>n-k-1 ) flag = 0;
for( r=1; r<=d1&&flag; r++ )
{
j = v[k+r].index; //后边d1个顶点每个顶点的序号
if( v[k+r].degree<=0 ) flag = 0;
v[k+r].degree--;
Edge[i][j] = Edge[j][i] = 1;
}
}
if( flag )
{
puts( "YES" );
for( p=0; p<n; p++ )
{
for( q=0; q<n; q++ )
{
if(q) printf( " " );
printf( "%d", Edge[p][q] );
}
puts( "" ); //换行
}
}
else puts( "NO" );
if(T) puts( "" ); //换行
}
return 0;
}