Havel—Hakimi定理:由非负数组成的非增序列s:d1,d2,···,dn(n>=2,d1>=1)是可图的,当仅当序列
s1:d2-1,d3-1,···,dd1+1 -1,dd1+2,····,dn
是可图的。序列s1中有n-1个非负数,s序列中d1后的前d1个度数减1后构成s1中的前d1个数。
判定过程:(1)对当前数列排序,使其呈递减
(2)从S【2】开始对其后S【1】个数字-1
(3)一直循环直到当前序列出现负数(即不是可图的情况)或者当前序列全为0 (可图)时退出。
例题:POJ 1659 Frogs' Neighborhood
代码:
1 #include <algorithm>
2 #include <iostream>
3 #include <cstring>
4 #include <cstdio>
5 using namespace std;
6 const int N= 16;
7 struct node
8 {
9 int degree; // 顶点的度数
10 int index; // 顶点的序号
11 }p[N];
12 int cmp( const void *a, const void *b)
13 {
14 return (( struct node *)b)->degree-(( struct node *)a)->degree;
15 }
16 int main()
17 {
18 int t,n,i,j,k,flag;
19 int map[N][N];
20 scanf( " %d ",&t);
21 while(t--)
22 {
23 scanf( " %d ",&n);
24 for(i= 0;i<n;i++)
25 {
26 scanf( " %d ",&p[i].degree);
27 p[i].index=i;
28 }
29 memset(map, 0, sizeof(map));
30 flag= 1;
31 for(j= 0;j<n&&flag;j++)
32 {
33 qsort(p+j,n-j, sizeof(p[ 0]),cmp); // 对p数组后n-j个元素排序
34 i=p[j].index;
35 int d=p[j].degree;
36 if(d>n-j- 1)
37 flag= 0;
38 for(k= 1;k<=d&&flag;k++)
39 {
40 int jj=p[j+k].index;
41 if(p[j+k].degree<= 0)
42 flag= 0;
43 p[j+k].degree--;
44 map[i][jj]=map[jj][i]= 1;
45 }
46 }
47 if(flag)
48 {
49 puts( " YES ");
50 for(i= 0;i<n;i++)
51 {
52 for(j= 0;j<n;j++)
53 {
54 if(j)
55 printf( " ");
56 printf( " %d ",map[i][j]);
57 }
58 puts( "");
59 }
60 }
61 else
62 puts( " NO ");
63 if(t)
64 puts( "");
65 }
66 }
2 #include <iostream>
3 #include <cstring>
4 #include <cstdio>
5 using namespace std;
6 const int N= 16;
7 struct node
8 {
9 int degree; // 顶点的度数
10 int index; // 顶点的序号
11 }p[N];
12 int cmp( const void *a, const void *b)
13 {
14 return (( struct node *)b)->degree-(( struct node *)a)->degree;
15 }
16 int main()
17 {
18 int t,n,i,j,k,flag;
19 int map[N][N];
20 scanf( " %d ",&t);
21 while(t--)
22 {
23 scanf( " %d ",&n);
24 for(i= 0;i<n;i++)
25 {
26 scanf( " %d ",&p[i].degree);
27 p[i].index=i;
28 }
29 memset(map, 0, sizeof(map));
30 flag= 1;
31 for(j= 0;j<n&&flag;j++)
32 {
33 qsort(p+j,n-j, sizeof(p[ 0]),cmp); // 对p数组后n-j个元素排序
34 i=p[j].index;
35 int d=p[j].degree;
36 if(d>n-j- 1)
37 flag= 0;
38 for(k= 1;k<=d&&flag;k++)
39 {
40 int jj=p[j+k].index;
41 if(p[j+k].degree<= 0)
42 flag= 0;
43 p[j+k].degree--;
44 map[i][jj]=map[jj][i]= 1;
45 }
46 }
47 if(flag)
48 {
49 puts( " YES ");
50 for(i= 0;i<n;i++)
51 {
52 for(j= 0;j<n;j++)
53 {
54 if(j)
55 printf( " ");
56 printf( " %d ",map[i][j]);
57 }
58 puts( "");
59 }
60 }
61 else
62 puts( " NO ");
63 if(t)
64 puts( "");
65 }
66 }