最大团问题(使用递归和非递归两种方法)
文章目录
- 问题描述
- 解决方法
- 递归回溯(递归)
- 迭代回溯(非递归)
- 测试样例及测试结果
问题描述
一个无向图 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-n的两种方法
/*** 使用递归打印1-10*/ public class Demo12 {public static void main(String[] args) {m(10);}public static ...
- python创建树结构、求深度_数据结构-树以及深度、广度优先遍历(递归和非递归,python实现)...
前面我们介绍了队列.堆栈.链表,你亲自动手实践了吗?今天我们来到了树的部分,树在数据结构中是非常重要的一部分,树的应用有很多很多,树的种类也有很多很多,今天我们就先来创建一个普通的树.其他各种各样的树 ...
- 二叉树的几种递归和非递归式遍历:
二叉树的几种递归和非递归式遍历: 1 #include <fstream> 2 #include <iostream> 3 4 using namespace std; 5 6 ...
- 全排列(含递归和非递归的解法)
全排列在近几年各大网络公司的笔试中出现的比较频繁 首先来看看题目是如何要求的(百度迅雷校招笔试题). 用C++写一个函数, 如 Foo(const char *str), 打印出 str 的全排列, ...
- C#实现(递归和非递归)快速排序和简单排序
C#实现(递归和非递归)快速排序和简单排序 本人因为最近工作用到了一些排序算法,就把几个简单的排序算法,想冒泡排序,选择排序,插入排序,奇偶排序和快速排序等整理了出来,代码用C#代码实现,并且通过了测 ...
- 分别用递归和非递归方式实现二叉树先序、中序和后序遍历(java实现)
分别用递归和非递归方式实现二叉树先序.中序和后序遍历 用递归和非递归方式,分别按照二叉树先序.中序和后序打印所有的节点.我们约定:先序遍历顺序 为根.左.右;中序遍历顺序为左.根.右;后序遍历顺序为左 ...
- 汉诺塔的改编题(用栈求解,分别递归和非递归)
限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间,求当塔有N层的时候,打印最优移动过程和最优移动总步数 例如:当塔为两层时,最上层的塔记为1,最下层的塔记为2,则 ...
- 树的先序遍历,中序遍历,后续遍历(递归和非递归实现)
前序遍历是先访问根节点再访问左子树最后访问右子树(中,左,右):中序遍历是先访问左子树再访问根节点最后访问右子树(左,中,右):后序遍历是先访问左子树再访问右子树最后访问根节点(左,右,中).---- ...
- 树与二叉树的深度优先与广度优先算法(递归与非递归)
本博客前面文章已对树与二叉树有过简单的介绍,本文主要是重点介绍有关二叉树的一些具体操作与应用 阅读本文前,可以先参考本博客 各种基本算法实现小结(三)-- 树与二叉树 和 各种基本算法实现小结( ...
最新文章
- docker(4)docker的网络,自定义网桥
- EasyExcel 2 上传 下载
- 这位教授2 年一篇 Science,再获教科书级的重大发现
- AfterLogic WebMail
- 11.1金山游戏开发笔试
- 如何安装Windows7多语言支持
- Java线程基础回顾及内存模型,看你还记得多少?
- S50VB100-ASEMI电机专用整流桥S50VB100
- Matlab里的数据类型
- 异数OS 织梦师-纤手(二)-- LPC RPC篇
- POJ1328(贪心)题解
- Pycharm安装第三方包报错怎么办
- 直播前、直播中、直播后...直播带货技巧大盘点
- 如何检测本计算机耗电量,如何查看我的电脑到底费不费电?
- 内网穿透是什么?哪些作用?
- 新海诚画集[秒速5センチメートル:樱花抄·學舍]
- ES6 标签模板(Tagged templates)
- 为什么我学51单片机很顺利,学STM32却一头雾水?
- 前端讲义64_AngularJS鼠标与键盘事件有关指令
- Unable to paint on Qt Widget, shows error “paintEngine: Should no longer be called”
热门文章
- 正点原子 Linux驱动开发学习笔记-06 chrdevbase虚拟设备驱动的完善
- 可控源音频大地电磁理论基础
- “登录”呢?还是“登陆”呢??
- 3050显卡驱动安装+配置pytorch的cuda环境
- 酞菁铜磺酸(CuPcS),酞青铜相对分子质量|齐岳生物
- oracle查询员工员工部门领导领导部门,oracle多表查询之经典面试题
- Hadoop退出安全模式
- 【二、八、十、十六】进制转换详解
- thinkphp 5.1 swoole扩展websocket使用教程
- android devik进程,suckit后门程序的分析 (二)