文章目录

  • 问题描述
  • 解决方法
    • 递归回溯(递归)
    • 迭代回溯(非递归)
  • 测试样例及测试结果

问题描述

​ 一个无向图 G = ( V , E ) G=(V,E) G=(V,E) , V V V 是点集, E E E 是边集。取 V V V 的一个子集 U U U ,若对于 U U U 中任意两个点 u u u 和 v v v,有边

( u , v ) ∈ E (u,v)\in E (u,v)∈E,那么称 U U U是 G G G的一个完全子图。 U U U 是一个团当且仅当 U U U 不被包含在一个更大的完全子图中。

G G G的最大团指的是定点数最多的一个团。

图例:

125
235
145
都是满足条件的最大团。


但是1235就不是,因为1,3之间没有边,不满足条件。

解决方法

使用回溯法解决最大团问题,本文提供两种方法,一种是递归写法,一种是非递归写法。时间复杂度均为 O ( 2 n ) O(2^n) O(2n)

递归回溯(递归)

代码:

#include<iostream>
using namespace std;
#define N 100
int bestn;
int n;
int node[N];
int x[N];
int a[N][N];
int cn;
void back(int k){//已经到达第k个节点 if(k>n){for(int i = 1;i<=n;i++)node[i] = x[i];bestn = cn; return;}int flag = 1;for(int i = 1;i<k;i++){if(x[i] ==  1&&!a[k][i]){//检查是否可以加入最大团中 flag = 0; break;}}if(flag){//可以加入,加入当前节点(进入左子树) x[k] = 1;cn++;back(k+1);//递归下一个节点 cn--;}else if(cn+n-k>bestn){//进入右子树,判断条件判断当前最好情况下是否比bestn大 x[k] = 0;//不选择当前节点 back(k+1);//进入下一个节点 }
}
int main(){cin>>n;for(int i = 1;i<=n;i++){for(int j = 1;j<=n;j++){cin>>a[i][j];}}back(1);cout<<"选择的最大团为: "; for(int i = 1;i<=n;i++){if(node[i]){cout<<i<<" ";}}cout<<endl;cout<<"节点个数为: "<<bestn; return 0;
}

解释:

示意图、邻接矩阵和解空间树如上图。


递归过程的示意图如图。

迭代回溯(非递归)

代码:

#include<iostream>
using namespace std;
#define N 100
int bestn;
int n;
int node[N];
int x[N];
int a[N][N];
int cn;
int back(){int k = 1;
while(1){int flag = 1;while(k<=n&&flag){for(int i = 1;i<k;i++){if(x[i] ==  1&&!a[k][i]){//检查是否可以加入最大团中 flag = 0; break;}}if(flag){x[k] = 1;cn++;k++;}    }if(k>n){for(int i = 1;i<=n;i++)node[i] = x[i];bestn = cn;}else {//进入右子树x[k] = 0;//不选择当前节点 k++;//进入下一个节点 }   while((cn+n-k <= bestn)){//当前最好情况下没有bestn大,说明这个子树没有作用,剪枝并且要回退。 k--;while(k>0&&x[k]==0){//从右子树一路回退 cn--;k--;}//回退到可能的左子树或者是根节点 if(k==0)return bestn;//根节点,返回 x[k] = 0;//不是根节点,则不选择这个节点,进入下一个节点 k++;}       }
}
int main(){cin>>n;for(int i = 1;i<=n;i++){for(int j = 1;j<=n;j++){cin>>a[i][j];}}back();cout<<"选择的最大团为: "; for(int i = 1;i<=n;i++){if(node[i]){cout<<i<<" ";}}cout<<endl;cout<<"节点个数为: "<<bestn; return 0;
}

解释:
对于上一个样例可作图如下:

构造一个新样例:(样例示意图在右下角)

测试样例及测试结果

样例一:

4
0 1 1 1
1 0 1 0
1 1 0 1
1 0 1 0

样例二:

5
1 1 0 1 1
1 1 1 0 1
0 1 1 0 1
1 0 0 1 1
1 1 1 1 1

样例三:

5
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

最大团问题(使用递归和非递归两种方法)相关推荐

  1. 递归打印1-n的两种方法

    /*** 使用递归打印1-10*/ public class Demo12 {public static void main(String[] args) {m(10);}public static ...

  2. python创建树结构、求深度_数据结构-树以及深度、广度优先遍历(递归和非递归,python实现)...

    前面我们介绍了队列.堆栈.链表,你亲自动手实践了吗?今天我们来到了树的部分,树在数据结构中是非常重要的一部分,树的应用有很多很多,树的种类也有很多很多,今天我们就先来创建一个普通的树.其他各种各样的树 ...

  3. 二叉树的几种递归和非递归式遍历:

    二叉树的几种递归和非递归式遍历: 1 #include <fstream> 2 #include <iostream> 3 4 using namespace std; 5 6 ...

  4. 全排列(含递归和非递归的解法)

    全排列在近几年各大网络公司的笔试中出现的比较频繁 首先来看看题目是如何要求的(百度迅雷校招笔试题). 用C++写一个函数, 如 Foo(const char *str), 打印出 str 的全排列, ...

  5. C#实现(递归和非递归)快速排序和简单排序

    C#实现(递归和非递归)快速排序和简单排序 本人因为最近工作用到了一些排序算法,就把几个简单的排序算法,想冒泡排序,选择排序,插入排序,奇偶排序和快速排序等整理了出来,代码用C#代码实现,并且通过了测 ...

  6. 分别用递归和非递归方式实现二叉树先序、中序和后序遍历(java实现)

    分别用递归和非递归方式实现二叉树先序.中序和后序遍历 用递归和非递归方式,分别按照二叉树先序.中序和后序打印所有的节点.我们约定:先序遍历顺序 为根.左.右;中序遍历顺序为左.根.右;后序遍历顺序为左 ...

  7. 汉诺塔的改编题(用栈求解,分别递归和非递归)

    限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间,求当塔有N层的时候,打印最优移动过程和最优移动总步数 例如:当塔为两层时,最上层的塔记为1,最下层的塔记为2,则 ...

  8. 树的先序遍历,中序遍历,后续遍历(递归和非递归实现)

    前序遍历是先访问根节点再访问左子树最后访问右子树(中,左,右):中序遍历是先访问左子树再访问根节点最后访问右子树(左,中,右):后序遍历是先访问左子树再访问右子树最后访问根节点(左,右,中).---- ...

  9. 树与二叉树的深度优先与广度优先算法(递归与非递归)

    本博客前面文章已对树与二叉树有过简单的介绍,本文主要是重点介绍有关二叉树的一些具体操作与应用 阅读本文前,可以先参考本博客 各种基本算法实现小结(三)-- 树与二叉树   和  各种基本算法实现小结( ...

最新文章

  1. docker(4)docker的网络,自定义网桥
  2. EasyExcel 2 上传 下载
  3. 这位教授2 年一篇 Science,再获教科书级的重大发现
  4. AfterLogic WebMail
  5. 11.1金山游戏开发笔试
  6. 如何安装Windows7多语言支持
  7. Java线程基础回顾及内存模型,看你还记得多少?
  8. S50VB100-ASEMI电机专用整流桥S50VB100
  9. Matlab里的数据类型
  10. 异数OS 织梦师-纤手(二)-- LPC RPC篇
  11. POJ1328(贪心)题解
  12. Pycharm安装第三方包报错怎么办
  13. 直播前、直播中、直播后...直播带货技巧大盘点
  14. 如何检测本计算机耗电量,如何查看我的电脑到底费不费电?
  15. 内网穿透是什么?哪些作用?
  16. 新海诚画集[秒速5センチメートル:樱花抄·學舍]
  17. ES6 标签模板(Tagged templates)
  18. 为什么我学51单片机很顺利,学STM32却一头雾水?
  19. 前端讲义64_AngularJS鼠标与键盘事件有关指令
  20. Unable to paint on Qt Widget, shows error “paintEngine: Should no longer be called”

热门文章

  1. 正点原子 Linux驱动开发学习笔记-06 chrdevbase虚拟设备驱动的完善
  2. 可控源音频大地电磁理论基础
  3. “登录”呢?还是“登陆”呢??
  4. 3050显卡驱动安装+配置pytorch的cuda环境
  5. 酞菁铜磺酸(CuPcS),酞青铜相对分子质量|齐岳生物
  6. oracle查询员工员工部门领导领导部门,oracle多表查询之经典面试题
  7. Hadoop退出安全模式
  8. 【二、八、十、十六】进制转换详解
  9. thinkphp 5.1 swoole扩展websocket使用教程
  10. android devik进程,suckit后门程序的分析 (二)