2021-05-01
CF11D A Simple Task
题意:给定一个无向图,求简单无向图的环数。保证没有重边(即不存在大小为2的环)。
注意到两种状态虽然经过的点相同,但是经过的点的顺序不一样,以及终点不一样,是不能算作相同的环的。
trick:对于每个简单环,我们都以环中序号最小的点为起点进行dfs。
#include<bits/stdc++.h>
using namespace std;
const int mx=20;
int n,m;
long long result;
int a[mx][mx];
int lazy[(1<<mx)+5][mx];
long long dp[(1<<mx)+5][mx];
long long dfs(int u,int x,int y) {
if(lazy[x][u]==y) return dp[x][u];
lazy[x][u]=y;
long long tot=0;
for(int v=1;v<=n;v++)
if(a[u][v]&&v>=y) {
if(v==y) tot++;
else if(!(x&(1<<v-1))) tot+=dfs(v,x+(1<<v-1),y);
}
return dp[x][u]=tot;
}
int main() {
scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) {
int x,y; scanf("%d%d",&x,&y),a[x][y]=a[y][x]=1;
}
for(int i=1;i<=n;i++) {
result+=dfs(i,1<<i-1,i);
}
printf("%lld",(result-m)/2);
}

浙公网安备 33010602011771号