题意:给你一列数,然后问你这列数是不是可图的,
这道题需要用到Havel-Hakimi定理的方法来构图
我先说一下这个定理:1.先把这列数排序
2.把这列数第一个数后面的没个数都-1。
3,删除第一个数,然后在排序重复步骤二
直到出现负数为止,如果出现负数说明是不可图的,如果出现都是0了 那就是可图的
举个例子:序列S:7,7,4,3,3,3,2,1
删除序列S的首项 7 ,对其后的7项每项减1,
得到:6,3,2,2,2,1,0,
继续删除序列的首项6,
对其后的6项每项减1,
得到:2,1,1,1,0,-1,
到这一步出现了负数,因此该序列是不可图的
在来个可图的吧:序列:4 3 1 5 4 2 1
排序之后:5 4 4 3 2 1 1
删除5对后面5个数减1操作
3 3 2 1 0 1
排序
3 3 2 1 1 0
删除3对后面3个数减1操作
2 1 0 1 0
排序
2 1 1 0 0
删除2 对后面2个数减1操作
0 0 0 0
全为0,可图
所以这道题就可以解了
下面看代码:好多东西我都在代码中写了 应该能看懂的
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef struct
{
int num;
int degree;
} MAP;
MAP mp[15];
int g[15][15];
int cmp(const void *a,const void *b)
{
return ((MAP *)b)->degree-((MAP*)a)->degree;
}
int main()
{
int n,j,T,i,k;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
memset(g,0,sizeof(g));
for(i = 0; i < n; i++)
{
scanf("%d",&mp[i].degree);
mp[i].num = i;
}
k = 0;
while(k < n)
{
qsort(mp + k,n - k,sizeof(mp[0]),cmp); //删除第一个数排序
if(mp[k].degree > n - k - 1) break;
for(i = 1; i <= mp[k].degree; i++)
{
if(mp[k + i].degree <= 0)break;//如果小于0退出循环
mp[k + i].degree--;
g[mp[k].num][mp[k+i].num]=g[mp[k+i].num][mp[k].num]=1;//对于k,后面d[k]个数指向k
}
if(i <= mp[k].degree)break;
k++;
}
if(k < n)printf("NO\n");
else
{
printf("YES\n");
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
if(j)printf(" ");
printf("%d",g[i][j]);
}
printf("\n");
}
}
if(T) printf("\n");
}
return 0;
}