1,Havel-Hakimi定理主要用来判定一个给定的序列是否是可图的。
2,首先介绍一下度序列:若把图 G 所有顶点的度数排成一个序列 S,则称 S 为图 G 的度序列。
3,一个非负整数组成的有限序列如果是某个无向图的序列,则称该序列是可图的。
4,判定过程:(1)对当前数列排序,使其呈递减,(2)从S【2】开始对其后S【1】个数字-1,(3)一直循环直到当前序列出现负数(即不是可图的情况)或者当前序列全为0 (可图)时退出。
5,举例:序列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,到这一步出现了负数,因此该序列是不可图的。
6,应用:http://poj.org/problem?id=1659
题意很简单,分析之后会发现其实本题的意思就是想问:给定一个非负数序列,问是不是一个可图的序列,即能不能根据这个序列构造一个图,有2种不合理的情况:(1)某次对剩下序列排序后,最大的度数(设为d1)超过了剩下的顶点数;(2)对最大度数后面的d1个数各减1后,出现了负数。
贴下代码:
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; struct node { int num,e; }x[15]; bool map[15][15]; int cmp(node a,node b) { if(a.num==b.num) return a.e<b.e; return a.num>b.num; } int judge(int n) { int i,num,tmp; while(1){ sort(x+1,x+n+1,cmp); if(!x[1].num) return 1;//数组全为 0 的情况退出 for(i=2;i<=x[1].num+1;i++){ if(x[i].num>0){ x[i].num--; map[x[1].e][x[i].e]=map[x[i].e][x[1].e]=1; } else return 0; } x[1].num=0; } } int main() { int n,t,i,j; bool flag; scanf("%d",&t); while(t--){ scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%d",&x[i].num); x[i].e=i; } memset(map,0,sizeof(map)); flag=judge(n); if(flag){ printf("YES/n"); for(i=1;i<=n;i++){ for(j=1;j<=n;j++) printf(j==1?"%d":" %d",map[i][j]); printf("/n"); } } else printf("NO/n"); if(t) printf("/n"); } return 0; }