zoukankan      html  css  js  c++  java
  • HavelHakimi定理(判断一个序列是否可图)

    判断一个有限序列是否是可图的,有Havel-Hakimi定理:

    由非负整数组成的非增序列s:d1,d2,~~~(省略号),dn(n>=2,d1>=1)

    是可图的,当且仅当序列:

    s1:d2-1,d3-1,~~~,d(d1+1) - 1,d(d1+2),~~~,dn是可图的。

    序列s1中有n-1个非负整数,s序列中d1后的前d1个度数减1后构成s1中的前d1个数。

    据此定理可以根据一个序列构造出相应的图(结果不唯一)

    实例:POJ 1659 青蛙的邻居

    注意:给每个顶点先编好号

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #define N 15
     5 struct vertex
     6 {
     7     int degree;      // 顶点的度
     8     int index;        //顶点的序号
     9 } V[N];
    10 int cmp(const void *a,const void *b)   //qsort中的cmp,逆序
    11 {
    12     return ((vertex *)b)->degree -((vertex *)a)->degree;
    13 }
    14 int main()
    15 {
    16     int t;
    17     int edge[N][N];   //图的邻接矩阵
    18     scanf("%d",&t);
    19     while(t--)
    20     {
    21         int flag = 2;  //用来标记判断结果
    22          int n;  //
    23         memset(edge,0,sizeof(edge));
    24 //        freopen("in.cpp","r",stdin);
    25 //        freopen("out.cpp","w",stdout);
    26         scanf("%d",&n);
    27         for(int i=0; i<n; i++)
    28         {
    29             scanf("%d",&V[i].degree);
    30             V[i].index = i;    //按输入顺序给湖泊编号
    31         }
    32         for(int k=0; k<n; k++)
    33         {
    34             qsort(V+k,n-k,sizeof(vertex),cmp); //对V数组后n-k个元素按非递增顺序排序
    35             if(V[k].degree > n-k-1 || flag == 0)   //不合理情形1:最大的度数超过了剩下的顶点数
    36             {
    37                 flag = 0;
    38                 break;
    39             }
    40             if(V[k].degree == 0 && flag != 0)   //序列中最大的数为0,且没有不合理情形,该序列可图
    41             {
    42                 flag = 1;
    43                 break;
    44             }
    45             for(int r = k+1; r < k+1+V[k].degree; r++)
    46             {
    47                 V[r].degree--;
    48                 if(V[r].degree< 0)   //不合理情形2:序列中出现了负数
    49                 {
    50                     flag = 0;
    51                     break;
    52                 }
    53                 edge[V[k].index][V[r].index] = edge[V[r].index][V[k].index] = 1;
    54             }
    55         }
    56         if(flag == 1)
    57         {
    58             puts("YES");
    59             for(int r=0; r<n; r++)
    60             {
    61                 for(int d = 0; d<n; d++)
    62                 {
    63                     printf("%d",edge[r][d]);
    64                     if(d != n-1)
    65                         printf(" ");
    66                 }
    67                 puts("");
    68             }
    69         }
    70         else
    71         {
    72             puts("NO");
    73         }
    74         if(t != 0)  puts("");
    75     }
    76     return 0;
    77 }
  • 相关阅读:
    真正VC++.net笔记1系统时间的获取
    真正VC++.net笔记5MessageBox变MessageBoxA?
    Judge Online 系统流程设计
    杂谈1:事情因每个人的参与而不同
    ESX/ESXi 4.1 Update 1 or later 同步NTP
    iSCSI CHAP认证
    JSTL中c:set标签的要点和技巧
    JSTL 判断对象是否为空
    Smartmontools——linux磁盘检测工具
    ECMAScript 对象类型
  • 原文地址:https://www.cnblogs.com/allh123/p/2958285.html
Copyright © 2011-2022 走看看