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);
}
posted @ 2021-05-01 10:21  仰望星空的蚂蚁  阅读(15)  评论(0)    收藏  举报  来源