A Simple Task CodeForces, taskcodeforces
A Simple Task CodeForces-11D
Question: number of simple loops that output an undirected graph. A simple ring refers to a ring without duplicate edges. Make sure that the graph has no secondary auto-ring.
Ans [I] [j] indicates the number of path entries that contain vertices in I, starting from the first vertex in I and ending with j.
For an I, enumerating the current end j (obviously not the first vertex) produces a state. Then enumerate the last end k. If it can be transferred, it will be transferred.
If the number of points in I is greater than 2 and the first point in j to I has a path, the ring is generated. At last, each ring is recorded twice and divided by 2.
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 typedef long long LL; 6 LL n,m; 7 bool ok[30][30]; 8 LL ans[1000000][22]; 9 LL anss;10 int main()11 {12 LL a,b,i,j,k,fi,p,pp;13 scanf("%lld%lld",&n,&m);14 for(i=1;i<=m;i++)15 {16 scanf("%lld%lld",&a,&b);17 ok[a][b]=ok[b][a]=true;18 }19 for(i=1;i<(1<<n);i++)20 {21 pp=__builtin_popcountll(i);22 if(pp==1)23 {24 //for(j=1;j<=n;j++)25 ans[i][__builtin_ffsll(i)]=1;26 }27 else28 {29 fi=__builtin_ffsll(i);30 for(j=1;j<=n;j++)31 if((i&(1<<(j-1)))&&j!=fi)32 {33 p=i^(1<<(j-1));34 for(k=1;k<=n;k++)35 if((p&(1<<(k-1)))&&ok[k][j])36 {37 ans[i][j]+=ans[p][k];38 }39 if(ok[j][fi]&&pp>2) anss+=ans[i][j];40 }41 42 }43 }44 printf("%lld",anss/2);45 return 0;46 }47 /*48 http://blog.csdn.net/fangzhenpeng/article/details/4907823349 http://blog.csdn.net/tobewhatyouwanttobe/article/details/3803612950 http://blog.csdn.net/kk303/article/details/962193351 http://blog.csdn.net/dreamon3/article/details/5134715152 */
Slightly improved
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 typedef long long LL; 6 LL n,m; 7 bool ok[30][30]; 8 LL ans[1000000][22]; 9 LL anss;10 int main()11 {12 LL a,b,i,j,k,fi,p,pp;13 scanf("%lld%lld",&n,&m);14 for(i=1;i<=m;i++)15 {16 scanf("%lld%lld",&a,&b);17 ok[a][b]=ok[b][a]=true;18 }19 for(i=1;i<(1<<n);i++)20 {21 pp=__builtin_popcountll(i);22 fi=__builtin_ffsll(i);23 if(pp==1)24 ans[i][fi]=1;25 else26 {27 for(j=fi+1;j<=n;j++)28 if((i&(1<<(j-1))))29 {30 p=i^(1<<(j-1));31 for(k=1;k<=n;k++)32 if((p&(1<<(k-1)))&&ok[k][j])33 ans[i][j]+=ans[p][k];34 if(ok[j][fi]&&pp>2) anss+=ans[i][j];35 }36 37 }38 }39 printf("%lld",anss/2);40 return 0;41 }42 /*43 http://blog.csdn.net/fangzhenpeng/article/details/4907823344 http://blog.csdn.net/tobewhatyouwanttobe/article/details/3803612945 http://blog.csdn.net/kk303/article/details/962193346 http://blog.csdn.net/dreamon3/article/details/5134715147 */