1. 程式人生 > >CodeForces - 11D A Simple Task

CodeForces - 11D A Simple Task

con directed ret 避免 title input break cat 大於

Discription

Given a simple graph, output the number of simple cycles in it. A simple cycle is a cycle with no repeated vertices or edges.

Input

The first line of input contains two integers n and m (1?≤?n?≤?19, 0?≤?m) – respectively the number of vertices and edges of the graph. Each of the subsequent m

lines contains two integers a and b, (1?≤?a,?b?≤?n, a?≠?b) indicating that vertices aand b are connected by an undirected edge. There is no more than one edge connecting any pair of vertices.

Output

Output the number of cycles in the given graph.

Examples

Input
4 6
1 2
1 3
1 4
2 3
2 4
3 4
Output
7

Note

The example graph is a clique and contains four cycles of length 3 and three cycles of length 4.

好像是很經典的一個問題呢。。。

狀壓dp,設 f[S][i] 為 從S的二進制最低位作為起點, 且經過S集合中的點,目前走到i的路徑種類。我們轉移的時候枚舉的點的編號 都必須大於 S的二進制最低位,這樣就可以避免重復計算了。

然後因為一個環會被正反走兩次,所以最後還要除以2。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=600005;
int ci[35],n,m;
bool v[35][35];
ll ans,f[maxn][20];

inline void solve(){
	for(int i=0;i<n;i++) f[ci[i]][i]=1;
	for(int S=1,now;S<ci[n];S++){
		now=S&-S;
		for(int i=0;i<n;i++) if(ci[i]==now){
			now=i;
			break;
		}
		
		for(int i=0;i<n;i++) if(f[S][i]){
			if(v[now][i]) ans+=f[S][i];
		    for(int j=now+1;j<n;j++) if(!(ci[j]&S)&&v[i][j]) f[S|ci[j]][j]+=f[S][i];
		}
	}
    
	ans=(ans-m)>>1;
}

int main(){
	ci[0]=1;
	for(int i=1;i<=20;i++) ci[i]=ci[i-1]<<1;
	int uu,vv;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&uu,&vv),uu--,vv--;
		v[uu][vv]=v[vv][uu]=1;
	}
	solve();
	cout<<ans<<endl;
	return 0;
}

  

CodeForces - 11D A Simple Task