HDU - 5823:color II (状压DP 反演DP)
2024-08-31 11:11:36
题意:给定连通图,求出连通图的所有子图的颜色数。 一个图的颜色数,指最少的颜色数,给图染色,使得有边相邻的点之间颜色不同。
思路:首先想法是DFS枚举,然后计算颜色,发现对于给定图,求颜色不会求? 毕竟是很乱的无向图。
那么考虑DP:dp[s]=min(dp[s0]+1),s0是s的子集,且满足s^s0是独立集。 那么复杂度是O(3^N);
因为有补集,还可以用反演DP???我第一次遇到。好菜啊,有机会补一下。
#include<bits/stdc++.h>
#define uint unsigned int
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
char c[][]; bool vis[maxn];
int q[maxn],tot,N; uint dp[maxn];
void check(int S)
{
rep(i,,S) vis[i]=,dp[i]=;
dp[]=;
rep(i,,S) {
tot=; bool F=;
rep(j,,N-) if(i&(<<j)) q[++tot]=j;
rep(j,,tot){
if(!F) break;
rep(k,,tot)
if(c[q[j]][q[k]]=='') {
F=; break;
}
}
if(F) vis[i]=;
}
}
int main()
{
int T,S;
scanf("%d",&T);
while(T--){
scanf("%d",&N); S=(<<N)-;
rep(i,,N-) scanf("%s",c[i]);
check(S);
for(int s=;s<=S;s++){
for(int i=s;;i=(i-)&s){
if(vis[i^s]){
dp[s]=min(dp[s],dp[i]+);
}
if(i==) break;
}
}
uint t=,ans=;
for(int i=;i<=S;i++){
t=t*;
ans+=t*dp[i];
}
cout<<ans<<endl;
}
return ;
}
最新文章
- PMD宣传文案
- HTTP 错误 500.19 - Internal Server Error 错误解决
- app——分享wap站,数据处理页面展示
- nodejs安装和环境搭建
- 灰色预测模型 c# 算法实现
- IOS把文件保存进沙盒目录
- 详细讲解Hadoop源码阅读工程(以hadoop-2.6.0-src.tar.gz和hadoop-2.6.0-cdh5.4.5-src.tar.gz为代表)
- google+ 登录API 使用 javascript sdk 快速入门 (图解)
- OC与JS交互前言-b
- WebMagic的设计参考了业界最优秀的爬虫Scrapy
- SQL SERVER 自定义函数 split
- Jvm垃圾回收堆内存变化过程
- Delphi 中的常用事件
- Android的Intent机制详解
- Spring+EhCache缓存实例(详细讲解+源码下载)
- SLAM+语音机器人DIY系列:(三)感知与大脑——1.ydlidar-x4激光雷达
- 【C#】多态
- Linux:Gentoo系统的安装笔记(四)
- git操作之git clean删除一些没有git add的文件
- CF449 (Div. 1简单题解)