分支限界——最大团问题

简介: 分支限界——最大团问题

给定有一个无向图,找出最大团个数。

最大团也就是该图中最大的完全图(各顶点之间都有边)。

image.png

算法思想:设p为所有点集的集合,依次取出p中的顶点作为团的起始点,也就是以该点为起点开始拓展,每次查看相邻顶点是否与团内各点联通,若true,则加入该点。

为了进一步降低时间复杂度,采取记忆化递归的方式,从后向前遍历顶点,用cnt数组记录该点以后所成最大团的个数,以此知该点的潜力,达到剪枝的效果。

#include<bits/stdc++.h>
using namespace std;
#define maxm 55
int g[maxm][maxm];//存图
int vis[maxm];//存放已选择的点
int cnt[maxm];//cnt[i]表示用编号>=i的点能组成的最大团的点数
int ans, n;
bool dfs(int cur, int num) {//从第cur个点开始向后添加,当前点是第num个
  for (int i = cur + 1; i <= n; i++) {
    if (cnt[i] + num <= ans)//当前点后的所有点组成的最大团的最大点数+已经加入的点数<=当前最佳答案(最好的情况都不可能超过当前最优解,则进行剪枝)
      return 0;
    if (g[cur][i])//两点相邻
    {
      int ok = 1;
      for (int j = 0; j < num; j++)//是否和当前已经加入团的所有点相邻
        if (!g[i][vis[j]])
        {
          ok = 0;
          break;
        }
      if (ok) {//当前点可以加入团中
        vis[num] = i;
        if (dfs(i, num + 1))//第一次dfs成功的一定是最大的
          return 1;
      }
    }
  }
  ans = max(ans, num);
  return (ans == max(num, ans) ? 0 : 1);
}
void maxclique() {
  for (int i = n; i > 0; i--)
  {
    vis[0] = i;
    dfs(i, 1);
    cnt[i] = ans;
  }
}
int main()
{
  cin >> n;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) {
      cin >> g[i][j];
      g[j][i] = g[i][j];
    }
  maxclique();
  cout << cnt[1];
  return 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
*/
相关文章
|
7月前
|
算法 调度
详解操作系统四大常用的作业调度算法(FCFS丨SJF丨HRRN丨RR)
详解操作系统四大常用的作业调度算法(FCFS丨SJF丨HRRN丨RR)
4357 0
|
7月前
|
前端开发 开发者 容器
|
7月前
|
SQL 关系型数据库 数据库
学习分布式事务Seata看这一篇就够了,建议收藏
学习分布式事务Seata看这一篇就够了,建议收藏
|
域名解析 弹性计算 运维
【运维】阿里云宝塔面板域名DNS解析(如何配置用域名访问网站)
【运维】阿里云宝塔面板域名DNS解析(如何配置用域名访问网站)
3732 0
【运维】阿里云宝塔面板域名DNS解析(如何配置用域名访问网站)
|
关系型数据库 MySQL Windows
mysql彻底卸载干净的5个步骤,超多图超详细保姆级教程最新教程新手小白轻松上手
mysql彻底卸载干净的5个步骤,超多图超详细保姆级教程最新教程新手小白轻松上手
14303 2
|
缓存 Linux 开发工具
CentOS 7- 配置阿里镜像源
阿里镜像官方地址http://mirrors.aliyun.com/ 1、点击官方提供的相应系统的帮助 :2、查看不同版本的系统操作: 下载源1、安装wget yum install -y wget2、下载CentOS 7的repo文件wget -O /etc/yum.
204894 0
|
7月前
|
算法 测试技术 编译器
【算法】优先队列式分支限界法,以01背包问题为例
📑 例题:01背包问题 题目链接:采药-洛谷 当洛谷上不让下载测试用例,可以试试:采药-ACWing
752 0
|
存储 算法 C++
虚拟存储管理(OPT,FIFO,LRU,LFU,NUR算法的C++实现)
虚拟存储管理(OPT,FIFO,LRU,LFU,NUR算法的C++实现)
479 1
|
缓存 监控 安全
Spring AOP 详细深入讲解+代码示例
Spring AOP(Aspect-Oriented Programming)是Spring框架提供的一种面向切面编程的技术。它通过将横切关注点(例如日志记录、事务管理、安全性检查等)从主业务逻辑代码中分离出来,以模块化的方式实现对这些关注点的管理和重用。 在Spring AOP中,切面(Aspect)是一个模块化的关注点,它可以跨越多个对象,例如日志记录、事务管理等。切面通过定义切点(Pointcut)和增强(Advice)来介入目标对象的方法执行过程。 切点是一个表达式,用于匹配目标对象的一组方法,在这些方法执行时切面会被触发。增强则定义了切面在目标对象方法执行前、执行后或抛出异常时所
9688 3
|
7月前
|
存储 Ubuntu 测试技术
Ubuntu镜像源cn.arichinve.ubuntu.com不可用原因分析和解决
源配置的是cn.archive.ubuntu.com,但是发现,系统更新时,自动去找了清华大学的Ubuntu源。
3286 0