Havel–Hakimi algorithm

来源:互联网 发布:ubuntu 16.04必装软件 编辑:程序博客网 时间:2024/06/06 13:17

Havel-Hakimi algorithm

可图:给定一个由非负整数数构成的列表(list),求解是否存在一个简单图,该图顶点的度数形成的列表与给定的列表相同。如果这样图是存在的。我们称该列表是可图的(graphic)。

        Havel-Hakimi 算法就是用于判断一个序列是否可图的。他建立于以下定理(Havel-Hakimi 定理

        已知非增列表S = {d[1],d[2],d[2],....d[n]},di∈N,则S可图的充分必要条件是S' = {d[2]-1,d[3]-1,...,d[d[1]+1]-1,...,d[n]},S'没有负数且可图。

        搜索了好久都没有找到严格的证明,下面只给出一个理解的方法,严格证明以后补上。

        必要性(<-):若S'可图,那么新增一个度数为的d[1]的点,向S'中部分边连线,必然可以将S'补成S。

        充分性(->):若S可图,设S对应的图是G,

        1.若G中存在E = {edge|edge = (1,2),(1,3)...(1,d[1]+1)}中的每条边,只需删除这些边即可。

        2.若这些边中的某些不存在,比如对于j>d[1]+1>i图中存在(1,j),但不存在(1,i),由于d[i]>=d[j],因此必有k满足图中存在edge(i,k),但无(j,k),我们只需(1,j)->(1,i);(i,k)->(j,k),这一变化不会导致i,j的度数改变但能将第二种情况变成第一种情况。

         

        这条定理给出了一个将图的规模降低的方法,我们还需要一个边界来判断一个规模较小的图是否可图。这里我们可以想象,对于每个度数为N的点,该图中至少要有N个其余的点,且每个点的度数都>1。有了这两条,我们就可以提出一个算法。

        对于给出的一个序列,

        1.将序列按照非升序排序,

        2.若序列中出现了负数或序列中元素的个数小于d[1]+1,则退出,报告失败

        3.删除d[1],将d[2]...d[2+d[1]]的所有元素减一

        4.回到1

其实还可以给出一个基于优先队列的实现版本,亲测可用

        1.将序列中所有非零元素入队(pri_que)

        2.将队首元素出队,记为A,若此时pri_que.size()<A,则退出,报告失败

        3.否则从队列中弹出A个元素。

        4.将这A个元素减一后的非零元素再次入队。

        5.若队列非空,回到2,否则退出报告失败。

具体可以去做一下POJ1659

        



0 0
原创粉丝点击