Havel-Hakimi定理
s是指所有点的度数;由非负整数组成的非增序列s:d1,d2,d3.....,dn(n>=2,d1>=1)是可图的(即能构成图)当且仅当
s1:d2-1,d3-1,...dn;是可图的;
例如:判断序列s:7,7,4,3,3,3,2,1是否可图。删除序列开头的7,对其后面的7项都减1,得6,3,2,2,1,0;继续删除6,
对其后6项减一,最后一位出现了负数,所以这个序列是不可图的;
例如:判断序列s:5,4,3,3,2,2,2,1,1,1是否可图。删除序列开头的5,对其后面的5项都减1,得3,2,2,1,1,2,1,1,1排序;
继续删除3,对其后3项减一,最后的0,0,0,0;由此判断该序列可图;
例:poj1659
hihoCoder挑战赛11来啦!有Tshirt作为奖品哦~
Language:
Frogs' Neighborhood
Time Limit: 5000MS Memory Limit: 10000K
Total Submissions: 8198 Accepted: 3482 Special Judge
Description
未名湖附近共有N个大小湖泊L1, L2, ..., Ln(其中包括未名湖),每个湖泊Li里住着一只青蛙Fi(1 ≤ i ≤ N)。如果湖泊Li和Lj之间有水路相连,则青蛙Fi和Fj互称为邻居。现在已知每只青蛙的邻居数目x1, x2, ..., xn,请你给出每两个湖泊之间的相连关系。
Input
第一行是测试数据的组数T(0 ≤ T ≤ 20)。每组数据包括两行,第一行是整数N(2 < N < 10),第二行是N个整数,x1, x2,..., xn(0 ≤ xi ≤ N)。
Output
对输入的每组测试数据,如果不存在可能的相连关系,输出"NO"。否则输出"YES",并用N×N的矩阵表示湖泊间的相邻关系,即如果湖泊i与湖泊j之间有水路相连,则第i行的第j个数字为1,否则为0。每两个数字之间输出一个空格。如果存在多种可能,只需给出一种符合条件的情形。相邻两组测试数据之间输出一个空行。
Sample Input
3
7
4 3 1 5 4 2 1
6
4 3 1 4 2 0
6
2 3 1 1 2 1
Sample Output
YES
0 1 0 1 1 0 1
1 0 0 1 1 0 0
0 0 0 1 0 0 0
1 1 1 0 1 1 0
1 1 0 1 0 1 0
0 0 0 1 1 0 0
1 0 0 0 0 0 0
NO
YES
0 1 0 0 1 0
1 0 0 1 1 0
0 0 0 0 0 1
0 1 0 0 0 0
1 1 0 0 0 0
0 0 1 0 0 0
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int n; 6 struct node 7 { 8 int id; 9 int val; 10 }a[100]; 11 bool cmp(node x,node y) 12 { 13 return x.val>y.val; 14 } 15 int map[20][20]; 16 int Havel() 17 { 18 int i,j; 19 for(i=0;i<n;i++) 20 { 21 sort(a+i,a+n,cmp);//每次都要排序 22 j=a[i].id;//记录头的坐标 23 int v=a[i].val; 24 if(v>n-i-1)//如果该点的度超过剩下的数 则不存在图 25 { 26 return 0; 27 } 28 for(int k=1;k<=v;k++)//开始减度 29 { 30 int x=a[k+i].id; 31 a[k+i].val--; 32 if(a[k+i].val<0)return 0;//为负数时2无图 33 map[j][x]=map[x][j]=1; 34 } 35 } 36 return 1; 37 } 38 int main() 39 { 40 int i,j,t; 41 scanf("%d",&t); 42 while(t--) 43 { 44 scanf("%d",&n); 45 memset(map,0,sizeof(map)); 46 for(i=0;i<n;i++) 47 { 48 scanf("%d",&a[i].val); 49 a[i].id=i; 50 } 51 int flag=Havel(); 52 if(!flag)printf("NO\n"); 53 else 54 { 55 printf("YES\n"); 56 for(i=0;i<n;i++) 57 { 58 for(j=0;j<n;j++) 59 { 60 if(j==0) 61 printf("%d",map[i][j]); 62 else printf(" %d",map[i][j]); 63 } 64 printf("\n"); 65 } 66 } 67 if(t) 68 puts("");//poj为什么没换行报wa,hdu上面还是有PE的 69 } 70 }