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; }