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

poj2989:All Friends(Bron–Kerbosch算法) 传送门 题意: 最大团计数。 题解: 这种题只能深搜了。。但是深搜要讲方法,有一种极大团计数高效算法,可以跑n=100" role="presentation">n=100n=100n=100的稠密图,甚至能跑上万的稀疏图,这就是Bron–Kerbosch算法。 算法流程(from wiki): BronKerbosch1(R, P, X): " role=" 阅读详情

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


以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 inefficient in the case of graphs with many non-maximal cliques: it makes a recursive call for every clique, maximal or not. To save time and allow the algorithm to backtrack more quickly in branches of the search that contain no maximal cliques, Bron and Kerbosch introduced a variant of the algorithm involving a "pivot vertex" u, chosen from P (or more generally, as later investigators realized,[4] from P ⋃ X). Any maximal clique must include either u or one of its non-neighbors, for otherwise the clique could be augmented by adding u to it. Therefore, only u and its non-neighbors need to be tested as the choices for the vertex v that is added toR in each recursive call to the algorithm. In pseudocode:

)

以上算法太朴素,搜索了大量不是极大团的点集。

为了节省时间和让算法更快的回溯,我们可以通过设定关键点 pivot vertex u。
对于任意的最大团,其必须包括顶点u或者u的非邻接点.否则就可以添加顶点u来扩充极大团,这显然矛盾.所以.我们只要测试 顶点u以及 u的非邻接点即可.这样可以节省递归的时间.

伪代码:

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

void dfs(int d, int an, int sn, int nn)
{
    if(sn == 0 && nn == 0) ++ S;
    int u = some[d][0];//pivot vertex
    for(int i = 0; i < sn; i ++)
    {
        int v = some[d][i];
        if(g[u][v]) continue;
        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;
    }
}
poj 2989代码:

/*
TechMonster
02.13.2016
*/
#include<stdio.h>
#include<iostream>
#include<string>
#include <algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#define pi acos(-1.0)
#define ls o<<1
#define rs o<<1|1
#define MS(x,y) memset(x,y,sizeof(x));
<span style="font-family: Arial, Helvetica, sans-serif;">#define MAXN 130</span>
const int MAXN = 0x3f3f3f3f;
const double eps = 1e-8;
void fre(){freopen("t.txt","r",stdin);}
using namespace std;
int N, M, a[MAXN], g[MAXN][MAXN];
int S, all[MAXN][MAXN], some[MAXN][MAXN], none[MAXN][MAXN];
//all为已取顶点集,some为未处理顶点集,none为不取的顶点集
//我们求最大团顶点数时只要some,要求记录路径时要all和some,这里求极大团数量,需要all、some、none
void dfs(int d, int an, int sn, int nn)
{
    if(S > 1000) return ; // 极大团数量超过1000就不再统计
    if(sn == 0 && nn == 0) ++ S;//sn==0搜索到终点,只有nn==0时,才是一个极大团
    int u = some[d][0];//pivot vertex
    for(int i = 0; i < sn; i ++)
    {
        int v = some[d][i];
        if(g[u][v]) continue;
        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;
    }
}
void process()
{
    S = 0;
    for(int i = 0; i < N; i ++) some[0][i] = i + 1;
    dfs(0, 0, N, 0);
    if(S > 1000) printf("Too many maximal sets of friends.\n");
    else printf("%d\n", S);
}
int main()
{
  //  fre();
    while(scanf("%d%d", &N, &M) == 2)
    {
        MS(g, 0);
        for(int i = 0; i < M; i ++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            g[x][y] = g[y][x] = 1;
        }      
        process();
    }
    return 0;
}


除此之外还有另一种优化方法:

An alternative method for improving the basic form of the Bron–Kerbosch algorithm involves forgoing pivoting at the outermost level of recursion, and instead choosing the ordering of the recursive calls carefully in order to minimize the sizes of the sets P of candidate vertices within each recursive call.

The degeneracy of a graph G is the smallest number d such that every subgraph of G has a vertex with degree d or less. Every graph has a degeneracy ordering, an ordering of the vertices such that each vertex has d or fewer neighbors that come later in the ordering; a degeneracy ordering may be found in linear time by repeatedly selecting the vertex of minimum degree among the remaining vertices. If the order of the vertices v that the Bron–Kerbosch algorithm loops through is a degeneracy ordering, then the set P of candidate vertices in each call (the neighbors of v that are later in the ordering) will be guaranteed to have size at most d. The set X of excluded vertices will consist of all earlier neighbors of v, and may be much larger than d. In recursive calls to the algorithm below the topmost level of the recursion, the pivoting version can still be used.[6][7]

In pseudocode, the algorithm performs the following steps:

   BronKerbosch3(G):
       P = V(G)
       R = X = empty
       for each vertex v in a degeneracy ordering of G:
           BronKerbosch2(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))
           P := P \ {v}
           X := X ⋃ {v}

没怎么研究,有兴趣自己看吧。。



Bron-Kerbosh算法求解极大团 Bron-Kerbosh算法求解极大团 参考资料:https://www.jianshu.com/p/437bd6936dad 这篇文章讲得很好,本文的代码也是参照这篇文章,用python实现。 什么是极大团? 团、极大团、最大团的定义请问这篇文章:https://www.jianshu.com/p/dabbc78471d7 为什么会用到极大团? 了解到极大团这个知识,是在构建任务指派模型的时候接触到的。在对任务进行指派时,每个任务都有其开始时间、结束时间,在不考虑员工资质的情况下,任务之间可能会存在时间上 阅读详情

相关推荐

POJ-2989-All Friends 极大团算法 Bron-Kerbosch及其改进

http://poj.org/problem?id=2989 给n个点m条边,求极大团的数量。 极大团的定义就是:对于一个团里,所有人互为朋友,且团外的任何一个人,都不会和团里的所有人同时是朋友。 BK算法的伪代码 BronKerbosch(All, Some, None): if Some and None are both empty:

缺氧 1910

最大独立集和最大完全子图

定义 最大独立集:当且仅当对于U 中任意点u 和v所构成的边(u , v) 不是G 的一条边时,U 定义了一个空子图。当且仅当一个子集不被包含在一个更大的点集中时,该点集是图G 的一个独立集(independent set ),同时它也定义了图G 的空子图。最大独立集是具有最大尺寸的独立集(摘自:百度百科:最大独立集)。 最大完全子图:图中任意两顶点都直接相连的图,称为完全图,也称全连接图。图...

FanJin的博客 1万+

Bron-Kerbosch 极大团发现算法:实现 Bron-Kerbosch 算法以查找无向图的所有极大团。-matlab开发

[MC] = MAXIMALCLIQUES(A,V_STR) 给定图的布尔邻接矩阵 A,使用 Bron-Kerbosch 算法以递归方式找到 A 上的所有最大团。 V_STR 是一个可选的输入字符串,带有要使用的 Bron-Kerbosch 算法的版本(“v1”或“v2”)。 版本 2 更快(并且是默认值),并且版本 1 被包含在内以供后代使用。 输出矩阵 MC 在其列中包含最大集团。 注意:此函数可用于通过提供 A 的补集作为输入图来计算图 A 的最大独立集。 注意:此函数可用于通过提供 A 的线图的补集作为输入图来计算图 A 的最大匹配。 参考:Bron、Coen 和 Kerbosch,Joep,“算法 457:查找无向图的所有集团”,ACM 通信,卷。 16,没有。 9, pp: 575–577, 1973 年 9 月。 参考:Cazals, F. 和 Karande,

无向图的极大团、最大团(Bron-Kerbosch算法)

描述:团就是最大完全子图。(极大团) 给定无向图G=(V,E)。如果U包含于V,且对任意u,v属于U且有(u,v)属于E,则称U是G的完全子图。 G的完全子图U是G的团当且仅当U不包含在G的更大的完全子图中,即U就是最大完全子图。 G的最大团是指G中所含顶点数最多的团。 // 最大团: V中取K个顶点,两点间相互连接 // 最大独立集: V中取K个顶点,两点间不连接 // 最大...

yo_bc的博客 3万+

AIOps探索 | 如何用大模型构建高效运维知识及智能问答平台(1)

好久没有分享AIOps相关干货了,最近大模型这么火,而且我们有客户已经基于大模型构建了知识及智能问答平台,需要在运维领域结合使用场景进行应用。为此,楼主从头到尾声梳理了一遍大模型在运维领域构建知识及智能问答平台的应用场景、技术实现,总结出来供大家一同探索,希望对大家理解和运用大模型有一定帮助~

智能运维及数据中台探索 2810

编译opencv4.2时出现undefined reference to `jpeg_default_qtables‘错误的解决方案

操作系统:kylinV10 opencv版本:4.2.0 在编译opencv4.2.0的版本时,出现undefined reference to `jpeg_default_qtables’的错误提示,导致openc编译中断,不能继续编译,所以这个错误必须解决。 解决方案 查看错误的名字,根据名字分析,很有可能是当前系统中没有安装jpeg第三方库,到 http://www.ijg.org/上下载最新的源码包 jpegsrc.v9e.tar.gz,按如下顺序开始编译安装: tar -xzvf jpegsr.

jndingxin的专栏 5106

极大团与networkx Bron-Kerbosch算法源码解读

我在基于最大团的图池化里提到了一点点Bron-Kerbosch算法,不过对这个算法还是没有太了解,今天单独拿出一篇文章来说这个算法。首先,https://www.jianshu.com/p/437bd6936dad 有着很详细的介绍,毕竟原论文太偏向于理论了不好读透。我会在其基础上添加一些我的理解,并解读networkx的源码。 Bron-Kerbosch算法 极大团的检索算法的时间复杂度都比较高,最近查资料发现也有许多研究旨在降低其时间复杂度,或者在稀疏的巨型图上应用,但是这些都需要对BK算法做一个深入理

qq_36618444的博客 3612

关于RTP时间戳以及播放器对时间戳的处理

首先,了解时间戳几个基本概念: 时间戳单位:时间戳计算的单位不是秒之类的单位,而是由采样频率所代替的单位,这样做的目的就是为了是时间戳单位更为精准。比如说一个音频的采样频率为8000Hz,那么我们可以把时间戳单位设为1 / 8000。 时间戳增量:相邻两帧之间的时间差(以时间戳单位为基准)。 采样频率: 有些地方也叫时钟频率,即 每秒钟抽取样本的次数,例如音频的采...

toshiba689的专栏 3052

POJ - 2989 All Friends 极大团

POJ - 2989点我点我 All Friends Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %lld & %llu Submit Status Description Sociologists are interested in the p

Free Cat~~~ 跳动的喵 1602

Android系统开机时间分析与优化指南

本文系统阐述了Android开机时间优化的全流程技术方案。首先详细解析了从电源键按下到桌面显示的完整启动流程及关键事件序列,然后介绍了秒表计时、日志分析和自动化脚本三种测量方法。重点从底层和上层两个维度提出了具体优化措施:底层包括编译器优化、内核驱动裁剪和日志精简;上层涵盖系统服务参数调整、应用预优化和功能组件精简。最后提供了验证工具和方法,并强调优化需要在性能、功耗和功能间取得平衡。通过这套系统化方案,可有效提升Android设备的开机速度与用户体验。

学无止境 352

SOME/IP协议详解「1.1·面向服务与面向信号」

面向信号和面向服务的区别,和举例子

雪云飞星的博客 5654

poj2989 All Friends(极大团)

题意:给出n个人,其中m对朋友,求最大团数量(就是在团中的人互为朋友,不在团中的人与某些在团中的人不互为朋友,在本题中人数不要求最多) 题解:要用Bron–Kerbosch算法。找最大团,我们设了三个数组:all, some, none,分别表示的是已经选了的点,还没动的点,不要的点(避免重复,实际上就是判重)。 算法的思想是将some中的点逐步加入all和none中,当我们将一个点...

一身清贫怎敢入繁华 706

企业 IoT 产品安全渗透测试与欧盟 CRA 合规落地实战指南

欧盟 CRA(网络弹性法案)2026-09-11 漏洞报告义务生效,2027-12-11 全面强制产品安全不再是"加分项",而是市场准入的法律门槛本文面向 IoT 企业安全工程师/运维工程师,讲清楚如何从零建立渗透测试能力,并与 CRA 合规要求对齐落地。不讲空话,全是可执行的步骤。IoT 企业安全工程师、运维工程师负责产品合规的技术人员想从"被动响应"转向"主动安全"的团队[ ] 能独立完成 Web 应用渗透测试并输出报告[ ] 能对 REST/GraphQL API 进行安全评估。

探索云原生与智能化驱动下的安全运维新范式。关注DevSecOps、可观测性、AIOps等前沿领域,与您共赴技术前沿。 269

「图论」Bron-Kerbosch 算法

7.21晚上加赛 T2.七负我,做这题找到了性质发现需要求最大团,不会,爆搜,打假了,赛后改,对了,但时间复杂度大爆炸,看下发题解,有这么一句话:于是学习了一下。 updated on 7.24 增加了图片演示方便理解; updated on 7.25 更新了 \(X\) 集合的作用和关键点优化的解释。 Bron-Kerbosch算法-求图的最大团,极大团 概念: 团:每个顶点都两两...

weixin_40386663的博客 612

虚拟电厂功率预测最佳实践白皮书

虚拟电厂(VPP)通过聚合分散的可再生能源资源,为电网提供可观测、可调度和可交易的解决方案。本文提出了一套功率预测方法论,并给出LSTM实现脚本,涵盖资源接入、数据治理、预测模型设计及市场交易闭环。针对风-光-储-负荷混合场景,该方法论强调轻量化部署和滚动优化,可有效提升预测精度和调度收益。未来研究将融合深度气象预报和强化学习,进一步优化VPP的协同调度能力。

专注AI大模型,软件混淆,授权 377

阿里云百炼全解析:一站式大模型开发平台的架构与行业实践

摘要: 阿里云百炼平台通过一站式架构革新大模型开发范式,将传统碎片化工具链整合为统一工作流,实现开发周期从月级到小时级的跃迁。其核心架构包含接入层、引擎层与资源层,关键技术突破包括MCP服务协议、多模态引擎及高性能训练优化。平台提供全生命周期开发支持,从数据准备到模型部署,并通过VPC隔离、数据加密构建企业级安全体系。已在医疗、电力等行业实现显著增效,如阿斯利康药物分析系统准确率提升至95%。未来将向多Agent协同、边缘计算等方向演进,推动AI技术深度融入产业核心。

fudaihb的博客 1989

Bron-kerbosch算法-求图的最大团,极大团

概念介绍: 团:每个顶点都两两相连 极大团:没有被包含在其他团中的团 最大团:顶点数最多的极大团 独立集:从图中取k个点,任意两点之间不连接 最大团顶点数量:等于补图中最大独立集顶点数 补图:在图论里面,一个图G的补图(complement)或者反面(inverse)是一个图有着跟G相同的点,而且这些点之间有相连当且仅当在G里面他们没有边相连。在制作图的时候,你可以先建立一个有G所有点的完全...

qq_40678690的博客 1812

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

SLAM匹配之无向图------最大团搜索算法总结

在图论中,团 (Clique)是图中一个顶点的子集,使得子集中任意两个顶点都有一条边相连。换句话说,一个团是一个完全子图。

lovely_yoshino的博客 1万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

最大团问题 Bron-Kerbosch算法

最大团即最大完全子图问题。正常的做法是,先从一个小集合开始,如果一个新点和这个集合每个元素都有一条边,那么这个新点就可以加到团中。 Bron-Kerbosch算法的特点是,无需显示判断新点是否和原来的集合有边。 R集合即为集合,P集合为搜索范围,由伪代码可见,每个点的邻居都要用交集处理。这样,只有所有人都有的邻居才能加入集合。X集合为不处理的点,如果不处理的点也是所有人的朋友,那就不是最大团(加入新点就不是团)。所以,此算法可以找到所有的最大团,很强。 ...

qq_39678022的博客 2576

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

学习一个 Bron-Kerbosch 算法

Bron-Kerbosch 算法计算图的最大全连通分量(团clique) 最大独立集: 顶点集V中取 K个顶点,其两两间无连接。 最大团: 顶点集V中取 K个顶点,其两两间有边连接。最大团中顶点数量 = 补图的最大独立集中顶点数量补图定义: G = #include<cstdio> #include<cstdlib> #include<cstring>int best; int num[ma

onepointo 2857

POJ 2989 All Friends (极大团数量 + 全局变量局部变量)

点击打开链接 题意:给出n个点,然后给出m组相邻的点,问极大团的数量。 核心是不变的,还是注意细节,细节如果出错,就会出现一些奇怪的结果。还有要知道怎么样做可以避免出错。 这道题三个集合里放的编号都应该是从1开始的,因为题设编号就是从1开始的。这样一定不会出错,事实证明从0开始的确不可以。 如果一个变量既定义了全局变量,又定义了局部变量,那么就可以看成是一个全局变量和一个局

Muya 934

Bron–Kerbosch算法求一般图最大团/最大独立集

最大团: V中取K个顶点,两点间相互连接 最大独立集: V中取K个顶点,两点间不连接 最大团数量 = 补图中最大独立集数 关于 Bron-Kerbosch算法(原文)   基础形式是一个递归回溯的搜索算法.通过给定三个集合 (R,P,X).   初始化集合R,X分别为空,而集合P为所有顶点的集合.   而每次从集合P中取顶点{v}, 当集合中没有顶点时,两种情况.   ...

REWINE 7720

最大团问题分支限界法_最大团问题与 Bron-Kerbosch 算法

最近注意到了图论中的最大团问题。最大团问题是一个 NP 完全问题,在此对它做简单介绍,并介绍具有代表性的 Bron-Kerbsch 算法。什么是一个团?最大团问题首先一个图的问题,假设读者已经知道图的概念。假设一个无向图 ,一个团是图 的子图,该子图中的所有顶点之间都有边将它们相连。极大团指的是,该团不包含于图 的任何其他团,即不是任何其他团的真子集。最大团指的是结点数量最多的极大团。最大团...

weixin_31971181的博客 1353

发现一个宝藏 Python 库,玩社区发现算法的不能错过!

网络是由一些紧密相连的节点组成的,并且根据不同节点之间连接的紧密程度,网络也可视为由不同簇组成。簇内的节点之间有着更为紧密的连接,不同簇之间的连接则相对稀疏。这种簇被称为**网络中的社区结构**(community structure)。

Trb401012的博客 1311

图论---极大团(POJ 2989,Hdu 1530)

1、极大团: 一个图G = (V,E),要求选取一个子图,这个图中的任意两个点都能相互到达,当这个子图的顶点数最多时, 这个图就是图G的极大团。 2、求解方法: Born_Kerbosch算法: (1)规定三个集合: R:极大团中所包含的顶点; P:未被匹配,还有可能加入极大团的点; X:已经被其他极大团匹配过的点,就是已经计数过的点,用于判断重复的极大团; (2)然...

积少成多,水滴石穿 916

算法笔记 --- Bron–Kerbosch算法-最大独立集与最大问题

定义 最大团:点数最多的极大团。 极大团:不是其他团的子团的团。 团:原图的完全子图。 最大独立集:一个点数最多的点集,且满足集合内的点互不相邻 性质 一个图的最大独立集的集合大小等于该图的补图的最大团大小 用于解决最大团问题的Bron–Kerbosch算法 简书上的图解 博客园的三种优化 优快云上的原理 #define N 1010 /* 最大团 = 补图G的最大独立集数 ———>最大独...

欢迎光临 我的心 1189
上一篇: hdu 1936 Emoticons :-)
下一篇: 高斯消元 模板 hdu2262 判断无穷解 接受无穷解 两种
QZQmmmm
博客等级 码龄11年 77粉丝 110原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值