给定一个非负整数列,判断其是否是可图的;
(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; }