第一行是测试数据的组数T(0 ≤ T ≤ 20)。每组数据包括两行,第一行是整数N(2 < N < 10),第二行是N个整数,x1, x2,..., xn(0 ≤ xi ≤ N)。实际上市给定一个非负整数序列,问你是不是一个可图的序列根据Havel-Hakimi定理
1、某次对剩下序列排序后,最大的度数(d1)超过了剩下的顶点数
2、对最大的度数后面的d1个度数各减1后,出现了负数一旦出现以上两种情形,则可判定该序列是不可图的
本体实现思路:
1:为了确保顶点序号与输入时保持度数顺序一致,特意声明一个vertex结构体,包含了顶点的度和序号两个成员
2:每次对剩下的顶点按度数从大到小顺序排序后,设最前面的顶点(及当前度数最大的顶点)序号为i、度数为d1,对后面d1个顶点每个顶点(序号设为j)度数减1,并连边,即在邻接矩阵Edge中设置Edge[i][j]和
Edge【i】【j】为1.
1、某次对剩下序列排序后,最大的度数(d1)超过了剩下的顶点数
2、对最大的度数后面的d1个度数各减1后,出现了负数一旦出现以上两种情形,则可判定该序列是不可图的
本体实现思路:
1:为了确保顶点序号与输入时保持度数顺序一致,特意声明一个vertex结构体,包含了顶点的度和序号两个成员
2:每次对剩下的顶点按度数从大到小顺序排序后,设最前面的顶点(及当前度数最大的顶点)序号为i、度数为d1,对后面d1个顶点每个顶点(序号设为j)度数减1,并连边,即在邻接矩阵Edge中设置Edge[i][j]和
Edge【i】【j】为1.
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
#include <climits>
#include <stack>
#include <algorithm>
#define long long ll
#define M 200
using namespace std;
#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 i, r, j;
int d1; //对剩下的序列排序后 第一个(度数最大的顶点)的度数
int T, n; //case 湖泊个数
int Edge[N][N], flag; //邻接矩阵,是否存在合理相邻关系的标志
scanf ("%d", &T);
while (T--)
{
scanf ("%d", &n);
for (int i = 0; i < n; i++)
{
scanf ("%d", &v[i].degree);
v[i].index = i;
}
memset (Edge, 0, sizeof(Edge));
flag = 1;
for (int k = 0; k <= n && flag; k++)
{
//对v数组后n-k个元素按非递增顺序排序
qsort (v+k, v-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];
}
}
if ( flag )
{
printf("YES");
for (int p =0; p < n; p++)
{
for (int q = 0; q < n; q++)
{
if (q) printf ( " " );
printf("%d", Edge[p][q]);
}
}
printf("\n");
}
else put ("NO");
if (T) put ( " ");
}
return 0;
}