题目链接

点我跳转

题目大意

给你一张完全图,你可以删除任意数量的边

要求删除完后剩余的所有子图必须是完全图

问完全子图数量最少是多少

解题思路

定义 \(ok[i]\) 表示状态为 \(i\) 时所对应的点构成的图是否为完全图 (\(1\) 为是 , \(0\) 为否)

判断完全图可直接暴力枚举任意两点检查是否有边

定义 \(dp[i]\) 表示状态为 \(i\) 时所对应的点构成的所有子图都为完全图,且子图数最小

其中 \(dp[0] = 0\)

那么不难得到当 \(ok[j] = 1\) 时

\(dp[i] = min(dp[i] , dp[i\) ^\(j] + 1)\) , ( \(j\) 为 \(i\) 的子集 )

答案为 \(dp[1 << n - 1]\)

AC_Code

#include<bits/stdc++.h>
using namespace std;
const int N = 1LL << 19 , M = 20;
int n , m , dp[N] , ok[N] , g[M][M];
signed main()
{
cin >> n >> m;
for(int i = 1 ; i <= m ; i ++)
{
int x , y;
cin >> x >> y;
g[x][y] = g[y][x] = 1;
}
int sum = 1 << n;
for(int i = 0 ; i < sum ; i ++)
{
ok[i] = 1;
for(int j = 1 ; j <= n ; j ++) if(i >> (j - 1) & 1)
{
for(int k = j + 1 ; k <= n ; k ++) if(i >> (k - 1) & 1)
{
if(!g[j][k]) { ok[i] = 0 ; break ; }
}
if(!ok[i]) break ;
}
dp[i] = 1e9;
}
dp[0] = 0;
for(int i = 0 ; i < sum ; i ++)
{
for(int j = i ; j ; j = (j - 1) & i) if(ok[j])
{
dp[i] = min(dp[i] , dp[i ^ j] + 1);
}
}
cout << dp[sum - 1] << '\n';
return 0;
}

最新文章

  1. tyvj1113 魔族密码
  2. CSS后代选择器可能的错误认识
  3. Extjs 一些配置以及方法
  4. 嵌入式(Embedded)Neo4j数据库访问方法
  5. MAC下利用Github 、hexo、 多说、百度统计 建立个人博客指南
  6. (转) 一步一步学习ASP.NET 5 (五)- TypeScript
  7. JS-页面操作
  8. [转]MYSQL远程登录权限设置
  9. 重新想象 Windows 8.1 Store Apps (77) - 控件增强: 文本类控件的增强, 部分控件增加了 Header 属性和 HeaderTemplate 属性, 部分控件增加了 PlaceholderText 属性
  10. 好网站:字体转换器在线转换 http://www.diyiziti.com/
  11. 框架设计——MVC IOC
  12. Apache Spark GraphX的使用简介
  13. python learning_curve函数
  14. HDU 1070 - Milk
  15. Callable、Future和FutureTask区别
  16. discuz相关总结
  17. SPRINGMVC中的中文乱码处理
  18. Codeforces 1053 B - Vasya and Good Sequences
  19. vue2.0过滤器
  20. H5音乐播放器【歌单列表】

热门文章

  1. maven依赖问题的出现原因与解决方式
  2. Python模块学习遇到的问题
  3. Win10激活失败并提示错误代码0xC004C003的解决方法
  4. WinForm 加载大数据时不闪烁的ListView
  5. 团队作业4-Day5
  6. GYM100526I Interesting Integers
  7. git 远端版本回退
  8. 通过git-bash 批量管理VMware虚拟机
  9. 20201214-1 Json与pickle数据序列化
  10. 小兔子有颗玻璃心A版【转】