(图论)使用Havel-Hakimi定理判断给出的序列是否可图

先行概念:

度序列(degree sequence):若把图 G所有顶点的度数排成一个序列 s,则称 s为图 G的度序 列。例如,图 1.1(a)所示无向图 G1的度序列为 s: 2, 5, 4, 3, 3, 1;或 s': 1, 2, 3, 3, 4, 5;或 s'': 5, 4, 3, 3, 2, 1。 其中序列 s 是按顶点序号排序的,序列 s'是按度数非减顺序排列的,序列 s''是按度数非增顺序排 列的。给定一个图,确定它的度序列很简单,但是其逆问题并不容易,即给定一个由非负整数组 成的有限序列 s,判断 s是否是某个图的度序列。 序列是可图的(graphic):一个非负整数组成的有限序列如果是某个无向图的度序列,则称 该序列是可图的。判定一个序列是否是可图的,有以下 Havel-Hakimi 定理。



引入正题

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个度数(即 d2~dd1+1)减 1 后构成 s1中的前 d1个数。 例如,判断序列 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,到这一步出现了负数。由于图中不可能存在负度数的顶点,因此该序列不是可图的。 再举一个例子,判断序列 s: 5, 4, 3, 3, 2, 2, 2, 1, 1, 1 是否是可图的。删除序列 s的首项 5,对其 后的 5项每项减 1,得到:3, 2, 2, 1, 1, 2, 1, 1, 1,重新排序后为:3, 2, 2, 2, 1, 1, 1, 1, 1。继续删除序 列的首项 3,对其后的 3项每项减 1,得到:1, 1, 1, 1, 1, 1, 1, 1。如此再陆续得到序列:1, 1, 1, 1, 1, 1, 0;1, 1, 1, 1, 0, 0;1, 1, 0, 0, 0;0, 0, 0, 0。由此可判定该序列是可图的。 Havel-Hakimi 定理实际上给出了根据一个序列 s构造图(或判定 s不是可图的)的方法:把序 列s按照非增顺序排序以后,其顺序为 d1, d2, …, dn;度数大的顶点(设为 v1),将它与度数次大 的前 d1 个顶点之间连边,然后这个顶点就可以不管了,即在序列中删除首项 d1,并把后面的 d1 个度数减 1;再把剩下的序列重新按非增顺序排序,按照上述过程连边;…;直到建出完整的图, 或出现负度数等明显不合理的情况为止。 例如,对序列 s: 3, 3, 2, 2, 1, 1构造图,设度数从大到小的 6个顶点为 v1~v6。首先 v1与v2、 v3、 v4连一条边,如图 1.4(a)所示;剩下的序列为 2, 1, 1, 1, 1。如果后面 4个1对应顶点 v3、v4、v5、 v6,则应该在 v2与v3、v2与v4之间连边,后在 v5与v6之间连边,如图(b)所示。如果后面 4个1 对应顶点 v5、v6、v3、v4,则应该在 v2与 v5、v2与 v6之间连边,后在 v3与 v4之间连边,如图(c) 所示。可见,由同一个可图的序列构造出来的图不一定是唯一的。(图论)使用Havel-Hakimi定理判断给出的序列是否可图_第1张图片

简单的来说:

执行过程如下:

1.先对度序列从大到小排序

2.选取第一个顶点的度为d,并将第一个顶点排除序列

3.对2-2+d内的顶点的度都减一。

重复执行这一个过程

判断不可图的条件:

1.在减一的过程中出现了负数

2.当前选取得到的d大于剩余的顶点的个数

以上条件满足其一都是不可图的


这里给出一个题目(hdoj的)

练习题目:http://acm.hdu.edu.cn/showproblem.php?pid=2454


在此给出我的解决代码

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;


const int MAXN=1005;
int seq[MAXN];

bool com(int a,int b)
{
    return a>b;
}

int main()
{
    int n;
    int m;
    cin>>n;
    while(n--)
    {
        cin>>m;
        int flag=1;
        for(int i=0;i<m;i++)
        {
            cin>>seq[i];
        }
        for(int i=0;i<m;i++)
        {
            sort(seq+i,seq+m,com);
            int d=seq[i];
            if(i+d>=m){
                flag=0;
                break;
            }
            for(int j=i+1;j<=i+d;j++)
            {
                seq[j]--;
                if(seq[j]<0){
                    flag=0;
                    break;
                }
            }
            if(!flag)
                break;
        }
        if(flag)
            cout<<"yes"<<endl;
        else
            cout<<"no"<<endl;
    }
 return 0;
}

文章前面的概念部分引用     王桂平、王  衍、任嘉辰 编著的《图论算法理论、实现及应用  》,如果不允许引用,请给我私信,我删除。


你可能感兴趣的:((图论)使用Havel-Hakimi定理判断给出的序列是否可图)