Havel-Hakimi定理,度序列,是否可图
题意:
输入一串数字,实际上就是一个图的度序列,判断图是否可图,并输出图的点元素矩阵,矩阵中1表示连通,0表示不连通。
分析:
Havel-Hakimi定理中,有两种情况是不可图的。
1. 某次对剩下序列排序后,最大的度数(设为d1)超过了剩下的顶点数;
2. 对最大的度数后面的d1个度数各减1后,出现了负数;
一旦出现以上任意一种情况,该图都不可图。
在输出中,需要构造图的邻接矩阵,有两点需要注意:
1. 建立一个结构体,包含该点的度数和序列号,保证顶点序号与输出的读书顺序一致;
2. 每次对剩下的顶点按度数从大到小排序后,设最前面的顶点(即当前度数最大的顶点)序号为i,度数为d1,并对后面的每个定点的度数减1,连边
(e[i][j] = e[j][i] = 1);
AC代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 15
int e[MAX][MAX];
struct ver{
int deg;
int num;
}v[MAX];
int cmp(const void *a, const void *b){
return (*( struct ver*)b).deg-(*(struct ver*)a).deg;
}
int main(){
int T,n,i,j;
scanf("%d",&T);
while(T--){
memset(v, 0, sizeof(v));
memset(e, 0, sizeof(e));
int flag = 1;
scanf("%d",&n);
for(i=0; i<n; i++){
scanf("%d",&v[i].deg);
v[i].num = i;
}
for(i=0; i<n&&flag; i++){
qsort(v+i, n-i, sizeof(v[0]), cmp);
int k = v[i].num;
int d1 = v[i].deg;
if(d1>n-i-1) flag = 0;
for(j=1; j<=d1&&flag; j++){
int h = v[i+j].num;
if(v[i+j].deg<=0) flag = 0;
v[i+j].deg--;
e[k][h] = e[h][k] = 1;
}
}
if(flag){
puts("YES");
for(i=0; i<n; i++){
for(j=0 ;j<n; j++){
printf("%d ",e[i][j]);
}
printf("%d",e[i][n]);
puts("");
}
}
else puts("NO");
if(T) printf("\n");
}
return 0;
}