namo,根本学不会状压DP
环的数量 - 题目 - Daimayuan Online Judge
题意:
思路:
小数据,第一个想到暴力或状压处理
这道题是状压DP
设dp[state][u]为:走过的点的状态为state,最后一个走的点是u
为什么还要多一维u,因为我们要判环,如果最后一个点和起点存在边,就将环计数(即考虑计算贡献)
因为我们处理的是无向环,因此可以设编号最小的是起点
然后就可以转移了
Code:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define lowbit(x) log2(x&(-x))
const int mxn=1e2+10;
const int mxe=5e4+10;
const int mod=1e9+7;
int n,m,u,v;
int G[mxn][mxn],dp[(1<<20)+10][20];
void solve(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>u>>v;
u--,v--;
G[u][v]=G[v][u]=1;
}
for(int u=0;u<n;u++) dp[1<<u][u]=1;
int ans=0;
for(int state=1;state<(1<<n);state++){
int st=lowbit(state);
for(int u=0;u<n;u++){
if(!((state>>u)&1)) continue;
if(G[u][st]) ans+=dp[state][u];
for(int v=st+1;v<n;v++){
if(!G[u][v]) continue;
if((state>>v)&1) continue;
dp[state|(1<<v)][v]+=dp[state][u];
}
}
}
cout<<(ans-m)/2<<'\n';
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int __=1;//cin>>__;
while(__--)solve();return 0;
}