CodeForces - 11D A Simple Task
Posted 蒟蒻JHY
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 11D A Simple Task相关的知识,希望对你有一定的参考价值。
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 mlines 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
4 6
1 2
1 3
1 4
2 3
2 4
3 4
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的主要内容,如果未能解决你的问题,请参考以下文章