状压dp好题.....算把..
http://codeforces.com/problemset/problem/11/D
题意很明确了 找多少个简单环
首先考虑环怎么找
简单的会想到 用状态压缩dp的方法
F[S][I]已经走过了S集合,且结束在I点的方案树
当出现一个环时,头尾一定相连,此时结束点以及可以表示出来了
考虑如何判断首尾相连,以及对于一个环来说,可能存在重复,这两个问题怎么解决
前面这个有点恶心,看一下后面这个怎么解决
这个重复问题,一般是固定一个点,然后再搞
那么问题来了固定那个点为起始点呢??
不失一般性的,我们以集合中lowbit位置的点作为起点
那么很显然,起点和终点都有了
可以愉快的进行dp了
又因为是无向图
显然有一条边别搞做一个环的情况,和环转的顺序不同的情况
于是答案要做相应处理....
到这里再仔细想想怎么写,过一过
经验:嘛,做题最好把已知问题罗列出来,然后(会发现可以帮助思考....(当然抄题解也是不错选择))
还有就是要考虑答案的不完全性
#includeusing namespace std; long long n,m,ans=0; long long tu[25][25]; long long f[1<<20][20]; int main(){ memset(tu,0x7f,sizeof(tu)); memset(f,0,sizeof(f)); cin>>n>>m; for(int i=1;i<=m;i++){ long long x,y; cin>>x>>y,tu[x-1][y-1]=tu[y-1][x-1]=1; } for(int i=0;i 1<1; for(int S=0;S<(1< ){ for(int i=0;i ){ if(!f[S][i])continue; for(int j=0;j ){ if(((1< 1)continue; if((1< S){ if((1< f[S][i]; } else{ f[S|(1< f[S][i]; } } } } cout<<(ans-m)/2<<endl; }