cf 11D A Simple Task(状压DP)
题意:
N个点构成的无向图,M条边描述这个无向图。
问这个无向图中共有多少个环。
(1 ≤ n ≤ 19, 0 ≤ m)
思路:
例子:
4 6
1 2
1 3
1 4
2 3
2 4
3 4
答案:7
画个图发现,直接暴力DFS有太多的重复计算。用DP。
枚举点数(状态),每个状态的起点、终点(起点可以不用枚举,因为反正是一个环,谁作为起点都一样)。
dp[S][i]:状态是S,i是终点 含义:从S中的第一个数s出发到达第i个点的方案数。如果s和i相加,总方案数ans+=dp[S][i]
dp[S][i]=sigma(dp[S'][i']) S'是去掉第i个点后的点集,i'属于S'且i'和i相连。
*结果除以2的原因:例:1-2-3-4-1 实际上和1-4-3-2-1是一样的。
代码:
int n,m;
char G[25][25];
int S[1<<19]; //全局状态
int cnS;
int P[25]; //全局指针
int cnP;
ll dp[(1<<19)+5][25];
ll ans; void finds(int nn,int fNum,int nowNum,int nowPos,int Ss){ //长度为nn,共要放fNum个,现在已放nowNum个,现在正在nowPos位置要进行第nowNum+1个放置的尝试
if(nowNum==fNum){
S[++cnS]=Ss;
return;
}
int t1=fNum-nowNum;
rep(i,nowPos,nn-t1+1){
int nSs=Ss+(1<<(i-1));
finds(nn,fNum,nowNum+1,i+1,nSs);
}
}
void calc(int nn,int S){ //总长度为nn,计算状态S哪些位置上为1,存在全局指针P【】中。
cnP=0;
rep(i,1,nn){
int t=(1<<(i-1));
if((S&t)>0){
P[++cnP]=i;
}
}
}
void init(){
cnS=0;
cnP=0;
finds(n,2,0,1,0);
mem(dp,0); rep(i,1,cnS){
int ss=S[i];
calc(n,ss);
rep(j,2,cnP){
if(G[P[1]][P[j]]==1){
dp[ss][P[j]]=1;
}
}
}
}
void solve(){
rep(i,3,n){ //状态由i个点构成
cnS=0;
cnP=0;
finds(n,i,0,1,0);
rep(tt,1,cnS){
int ss=S[tt];
calc(n,ss);
rep(j,2,cnP){
int pj=P[j]; //终点
int nss=ss-(1<<(pj-1)); //上一个状态
rep(k,2,cnP){ //枚举终点
if(k==j) continue;
if(G[pj][P[k]]==0) continue;
int pk=P[k];
dp[ss][pj]+=dp[nss][pk];
}
if(G[P[1]][pj]==1){
ans+=dp[ss][pj];
}
}
}
}
} int main(){
cin>>n>>m; mem(G,0);
while(m--){
int a,b;
scanf("%d%d",&a,&b);
G[a][b]=G[b][a]=1;
} if(n==1 || n==2){
puts("0");
}
else{
init();
ans=0;
solve();
printf("%I64d\n",ans/2);
} return 0;
}
cf 11D A Simple Task(状压DP)的更多相关文章
- CF11D A Simple Task 状压DP
传送门 \(N \leq 19\)-- 不难想到一个状压:设\(f_{i,j,k}\)表示开头为\(i\).结尾为\(j\).经过的点数二进制下为\(k\)的简单路总数,贡献答案就看\(i,j\)之间 ...
- CF 11D A Simple Task 题解
题面 这道题的数据范围一看就是dfs或状压啦~ 本文以状压的方式来讲解 f[i][j]表示目前的节点是i,已经经历过的节点的状态为j的简单环的个数: 具体的转移方程和细节请看代码: PS:(i& ...
- CF11D A Simple Task(状压DP)
\(solution:\) 思路大家应该都懂: 状压DP:\(f[i][j]\),其中 \(i\) 这一维是需要状压的,用来记录19个节点每一个是否已经走过(走过为 \(1\) ,没走为 \(0\) ...
- FZU - 2218 Simple String Problem(状压dp)
Simple String Problem Recently, you have found your interest in string theory. Here is an interestin ...
- FZU - 2218 Simple String Problem 状压dp
FZU - 2218Simple String Problem 题目大意:给一个长度为n含有k个不同字母的串,从中挑选出两个连续的子串,要求两个子串中含有不同的字符,问这样的两个子串长度乘积最大是多少 ...
- codeforces Diagrams & Tableaux1 (状压DP)
http://codeforces.com/gym/100405 D题 题在pdf里 codeforces.com/gym/100405/attachments/download/2331/20132 ...
- fzu2188 状压dp
G - Simple String Problem Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & ...
- HDU5816 Hearthstone(状压DP)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5816 Description Hearthstone is an online collec ...
- BZOJ-1087 互不侵犯King 状压DP+DFS预处理
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2337 Solved: 1366 [Submit][ ...
随机推荐
- 图的遍历BFS广度优先搜索
图的遍历BFS广度优先搜索 1. 简介 BFS(Breadth First Search,广度优先搜索,又名宽度优先搜索),与深度优先算法在一个结点"死磕到底"的思维不同,广度优先 ...
- 【tp3.2】根据不同域名来加载不同的配置文件
遇到问题: 最近遇到一个需求,需要多个公众号使用同一个项目,这就导致了不同公众号访问的数据库和公众号配置不同. 解决思路: 查看文档:http://document.thinkphp.cn/manua ...
- 怎样在Linux中查看apache是用那个httpd.conf
第一步:找到apache启动命令: [root@WAPBJ01 ~]# ps -ef|grep httpdroot 10575 1 0 19:45 ? 00:00:03 ...
- Shell系列(14)- declare声明变量
declare声明变量类型 格式 declare [+/-] [选项] [变量名] 选项 -:给变量设定类型属性 +:取消变量的类型属性 -a :将变量声明为数组型 -i :将变量声明为整数型(int ...
- 有哪些浏览器还支持flash?
Flash是大名鼎鼎的全家桶公司Adobe设计的一款网页动画软件,早期的动态网页基本都是基于Flash开发的.但是后来不断爆出关于Flash的安全漏洞和运行效率问题,虽然Adobe公司一直在尝试解决, ...
- requests接口自动化-excel参数化
在数据量大的时候,需要使用文件参数化. excel文件是其中一种. 安装xlrd读取excel文件.(这里是在pycharm安装) 发现选择豆瓣安装失败,阿里云安装成功. 准备excel文件,放在te ...
- javascript base64 encode decode 支持中文
* 字符编码 ** 一定要知道数据的字符编码 ** 使用utf-8字符编码存储数据 ** 使用utf-8字符编码输出数据 * Crypto.js 支持中文 Base64编码说明 Base64编码要求把 ...
- windos10环境下编译python3版pjsua库
环境:windows10_x64python3.9_x64pjsua-2.10vs2015 pjsua编译参考这里: https://www.cnblogs.com/MikeZhang/p/pjsip ...
- 用C++实现的数独解题程序 SudokuSolver 2.2 及实例分析
SudokuSolver 2.2 程序实现 根据 用C++实现的数独解题程序 SudokuSolver 2.1 及实例分析 里分析,对 2.1 版做了一些改进和尝试. CQuizDealer 类声明部 ...
- c++中的数学函数
math.h 数学函数库,一些数学计算的公式的具体实现是放在math.h里,具体有:1 三角函数double sin (double);double cos (double);double tan ( ...