最大团 极大团 Bron–Kerbosch算法 poj 2989

本文介绍了最大团问题,并以POJ 2989题为例,详细讲解了Bron-Kerbosch算法的基本形式和存在的效率问题。通过引入关键点(pivot vertex)优化算法,避免搜索非极大团,以减少递归的时间。同时,文章提到了利用图的退化度(degeneracy)进行进一步优化,确保候选顶点集合大小不超过退化度,从而提高算法效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

昨日老刘开了最大团专题后,起初以为挺简单,后来发现有点麻烦。能用的资料又很少。分享一下学习的东西


以poj 2989为例,题意是求 不同极大团的数量

要用Bron–Kerbosch算法


首先是最朴素的伪代码,没有任何剪枝(来自维基百科)https://en.wikipedia.org/wiki/Bron%E2%80%93Kerbosch_algorithm

   BronKerbosch(All, Some, None):
       if Some and None are both empty:
           report All as a maximal clique
       for each vertex v in Some:
           BronKerbosch1(All ⋃ {v}, Some ⋂ N(v), None ⋂ N(v))
           Some := Some \ {v}
           None := None ⋃ {v}


N(v)为顶点v相邻的点。

all为已取的顶点集,some为未处理顶点集(初始状态是全部顶点),none为不取的顶点集


最大团类型的题目中,我们求最大团顶点数时只要some,要求记录路径时要all和some,这里求极大团数量,需要all、some、none。

c代码:

void dfs(int d, int an, int sn, int nn)
//d为搜索深度,an、sn、nn分别为all、some、none集合中顶点数,
{
    if(sn == 0 && nn == 0) ++ S;//sn==0搜索到终点,只有nn==0时,才是一个极大团,S为极大团数量
    for(int i = 0; i < sn; i ++)
    {
        int v = some[d][i];
        int tsn = 0, tnn = 0;
        for(int j = 0; j < an; j ++) all[d + 1][j] = all[d][j];
        all[d + 1][an] = v;
        for(int j = 0; j < sn; j ++)if(g[v][some[d][j]]) some[d + 1][tsn ++] = some[d][j];
        for(int j = 0; j < nn; j ++) if(g[v][none[d][j]]) none[d + 1][tnn ++] = none[d][j];
        dfs(d + 1, an + 1, tsn, tnn);
        //把v从some取出,放入none
        some[d][i] = 0, none[d][nn ++] = v;
    }
}


原文:

The basic form of the algorithm, described above, is inefficien

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值