【问题描述】

当 G′ 是图 G 的子图,且 G′ 是关于 V′ 的完全图时,子图 G' 为图 G 的团;当 G' 是团,且不是其他团的子集时,G' 为图 G 的极大团;当 G' 是极大团时,且点数最多,G' 为图 G 最大团

当 G′ 中所有点不相邻,最大点集最大的图 G′ 为图 G 的最大独立集,且最大独立集数=补图的最大团

当用个数最少的团覆盖图 G 所有的点时,称为最小团覆盖,由于每个团中最多取一个点,因此有最大独立集<=最小团覆盖

简单来说,极大团是增加任一顶点都不再符合定义的团,最大团是图中含顶点数最多的极大团,最大独立集是除去图中的团后的点集,而最大团问题就是在一个无向图中找出一个点数最多的完全图。

对于弦图来说,求最大团一般使用 MCS 算法,而对于一般图来说,常使用 Bron-Kerbosch 算法

关于弦图的最大团:点击这里

【Bron-Kerbosch 算法】

Bron-Kerbosch 算法用于计算图中的最大的全连通分量,即计算图的最大团。

1.算法原理

Bron-Kerbosch 算法的基础形式是一个递归回溯的搜索算法,其通过给定三个集合:R、P、X 来递归的进行搜索

  1. 初始化集合 R、X 分别为空,集合 P 为所有顶点的集合
  2. 每次从集合 P 中取顶点 {vi},当集合中没有顶点时,有两种情况:
    1)集合 R 是最大团,此时集合 X 为空
    2)无最大团,此时回溯
  3. 对于每一个从集合 P 中取得的顶点 {vi},有如下处理:
    1)将顶点 {vi} 加到集合 R 中,集合 P、X 与顶点 {vi} 得邻接顶点集合 N{vi} 相交,之后递归集合 R、P、X
    2)从集合 P 中删除顶点 {vi},并将顶点 {vi} 添加到集合 X 中
    3)若集合 P、X 都为空,则集合 R 即为最大团

总的来看,就是每次从集合 P 中取 vi 后,再从 P∩N{vi} 集合中取相邻结点,保证集合 R 中任意顶点间都两两相邻

伪代码过程

BronKerbosch1(R,P,X):if P and X are both empty:report R as a maximal cliquefor each vertex v in P:BronKerbosch1(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))P := P \ {v}X := X ⋃ {v}

2.算法优化

对于基础的算法,由于其递归搜索了所有情况,对其中有些不是最大团的也进行了搜索,效率不高,为了节省时间让算法更快的回溯,可以通过设定关键点来进行搜索。

由于对于任意的最大团,其必须包括顶点 {u} 或 N-N{u},不然其必然需要通过添加它们来进行扩充,这显然矛盾,所以仅需测试顶点 {u} 以及 N-N{u} 即可。

伪代码过程:

BronKerbosch2(R,P,X):if P and X are both empty:report R as a maximal cliquechoose a pivot vertex u in P ⋃ Xfor each vertex v in P \ N(u):BronKerbosch2(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))P := P \ {v}X := X ⋃ {v}

由于其是通过选择特殊点,来进行最小化递归调用,一定程度上节省了时间,但还可以与降序的方式结合使用,来保证在线性的时间内求子图的最大团

伪代码过程:

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

3.实现

int n,m;
bool G[N][N];
int cnt[N];//cnt[i]为>=i的最大团点数
int group[N];//最大团的点
int vis[N];//记录点的位置
int res;//最大团的数目
bool dfs(int pos,int num){//num为当前独立集中的点数for(int i=pos+1;i<=n;i++){if(cnt[i]+num<=res)//剪枝,若取i但cnt[i]+已经取了的点数仍<ansreturn false;if(G[pos][i]){//与当前团中元素比较,取Non-N(i)int j;for(j=0;j<num;j++)if(!G[i][vis[j]])break;if(j==num){//若为空,则皆与i相邻,则此时将i加入到最大团中vis[num]=i;if(dfs(i,num+1))return true;}}}if(num>res){//每添加一个点最多使最大团数+1,后面的搜索就没有意义了for(int i=0;i<num;i++)//最大团的元素group[i]=vis[i];res=num;//最大团中点的数目return true;}return false;
}
void maxClique(){res=-1;for(int i=n;i>0;i--){//枚举所有点vis[0]=i;dfs(i,1);cnt[i]=res;}
}
int main(){int T;scanf("%d",&T);while(T--){memset(G,0,sizeof(G));scanf("%d%d",&n,&m);for(int i=0;i<m;i++){int x,y;scanf("%d%d",&x,&y);G[x][y]=1;G[y][x]=1;}//建立反图for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(i==j)G[i][j]=0;elseG[i][j]^=1;}}maxClique();if(res<0)res=0;printf("%d\n",res);//最大团的个数for(int i=0;i<res;i++)//最大团中的顶点printf("%d ",group[i]);printf("\n");}return 0;
}

【例题】

  1. Maximum Clique(HDU-1530)(模板题):点击这里
  2. Graph Coloring(POJ-1419)(模板题):点击这里

图论 —— 最大团问题相关推荐

  1. 图论——最大团问题和最大独立集、二分图相关

    文章目录 最大团问题和最大独立集 二分图.用网络流解决最大二分匹配的方法 一种另类的增广路--交替路.匈牙利算法 一般图.二分图中的其它性质 P1640 [SCOI2010]连续攻击游戏 最大团问题和 ...

  2. 图论 最大团,最大独立集

    经典的NP完全问题,只有暴力解,时间复杂度O(n2^n) 对于无向图来说 所谓最大团, 其实就是找一个最大完全子图,最大就是包含的点最多. 而最大独立集 == 补图的最大团 这里使用深度优先搜索实现, ...

  3. 回溯、图论——最大团问题(求最大完全子图)

     1.问题分析 要想解决最大团问题,也就是求最大完全子图.我们需要了解相关概念,现在有如下图: (1)完全子图: 给定无向图G=(V,E),其中V是顶点集,E是边集.G'=(V',E')如果顶点集V' ...

  4. 图论——强连通分量(Tarjan算法)

    文章目录 强连通分量 利用Tarjan算法求强连通分量 来一道例题练手(USACO08DEC) 图论文章汇总 强连通分量 什么是强连通图? 如果一个有向图中,存在一条回路,所有的结点至少被经过一次,这 ...

  5. 领域应用 | 图数据库及其在恒昌的应用简介

    首发于知乎专栏知识图谱和智能问答,作者为量子胖比特. 背景 历史上,多数企业级应用都运行在一个关系型数据库上(RDBMS),近年来,随着数据存储技术的飞速发展,关系型数据库在灵活性和可伸缩性方面不再处 ...

  6. PAT甲级1142 Maximal Clique :[C++题解]图论、最大团、枚举

    文章目录 题目分析 题目链接 题目分析 来源:acwing 分析: 团:团是顶点的集合,满足该集合中任意两顶点之间都有边. 判断是不是团:所有点是否有边 判断最大团:是否可以加一个额外点,使得所有点之 ...

  7. 【每日算法】【图论】【最小边覆盖 最小路径覆盖 最小顶点覆盖 最大独立集 最大团】

    最小边覆盖 = 最大独立集 = |V| - 最大匹配数 这个是在原图是二分图上进行的 最小路径覆盖和最小边覆盖不同,不要求给的图是二分图,而是要求是N x N的有向图,不能有环,然后根据原图构造二分图 ...

  8. 【HDU - 1530】Maximum Clique(最大团问题,图论)

    题干: Given a graph G(V, E), a clique is a sub-graph g(v, e), so that for all vertex pairs v1, v2 in v ...

  9. 【最大团】【HDU1530】【Maximum Clique】

    先上最大团定义: 最大团问题(Maximum Clique Problem, MCP)是图论中一个经典的组合优化问题,也是一类NP完全问题,在国际上已有广泛的研究,而国内对MCP问题的研究则还处于起步 ...

最新文章

  1. 在WinForm应用程序中嵌入WPF控件(转)
  2. MySQL REGEXP:正则表达式查询
  3. R语言观察日志(part6)--初识rMarkdown
  4. python精通难_Python 为什么入门容易 精通难
  5. 内存缓存MemoryCache
  6. vscode禁用 json 添加注释时的报错
  7. 「Photoshop 入门教程」如何在Mac版 Photoshop 中打开图像?
  8. 零中频接收机频率转换图_VHF跳频电台接收机射频前端的仿真设计
  9. c++——使用PlaySound()播放声音
  10. 数学知识都是计算机,数学在计算机的作用
  11. com.android.pngp.tln,杂七杂八的记录
  12. sql中between and 用法
  13. Vmware虚拟机ikuai路由配置
  14. Matlab--优化工具箱
  15. 计算机能学设计吗,计算机平面设计难学吗
  16. 英文版-Hillsong现场演唱-神羔羊配得-《Worthy Is the Lamb》
  17. 融媒体网络营销WSEO案例分享:两天内与大型网站有相同排名
  18. HTML常见标签的用法
  19. resilience4j-ratelimiter:限流器
  20. 计算机windows7启动不了桌面,电脑开机进不了桌面,教您电脑开机进不了桌面怎么办...

热门文章

  1. 大拐点!16省,人口开始负增长了
  2. 黑客魔术!如何黑掉一台根本不联网的电脑
  3. linux内核Kconfig语法
  4. docker -v 覆盖了容器中的文件_「安定坊」安全卫士-容器漏洞评估
  5. 面试官:缓存一致性问题怎么解决?
  6. 求你了,别再随便打日志了,教你动态修改日志级别!
  7. 聊聊领域分析与业务建模
  8. JEECG开源说明:JEECG 完全开源,不收任何费用,可以任用于商业!
  9. JAVA编程多线程面试常见知识点灵魂拷问(一)
  10. T1042/T2080芯片工控主板对比