bzoj 1488: [HNOI2009]图的同构【polya定理+dfs】
把连边和不连边看成黑白染色,然后就变成了 https://www.cnblogs.com/lokiii/p/10055629.html
这篇讲得好!https://blog.csdn.net/wzq_qwq/article/details/48035455
#include<iostream>
#include<cstdio>
using namespace std;
const int N=65,mod=997;
int n,m=2,fac[N],ans,a[N];
int gcd(int a,int b)
{
return !b?a:gcd(b,a%b);
}
int ksm(int a,int b)
{
int r=1;
while(b)
{
if(b&1)
r=r*a%mod;
a=a*a%mod;
b>>=1;
}
return r;
}
void dfs(int w,int s,int y)
{
if(!y)
{
int c=0,tot=1;
int nw=1;
for(int i=1;i<w;i++)
c+=a[i]/2;
for(int i=1;i<w;i++)
for(int j=i+1;j<w;j++)
c+=gcd(a[i],a[j]);
for(int i=1;i<w;i++)
nw=nw*a[i]%mod;
for(int i=2;i<w;i++)
{
if(a[i]!=a[i-1])
nw=nw*fac[tot]%mod,tot=0;
tot++;
}
nw=fac[n]*ksm(nw*fac[tot]%mod,mod-2)%mod;
ans=(ans+nw*ksm(m,c))%mod;
}
if(y<s)
return;
for(int i=s;i<=y;i++)
{
a[w]=i;
dfs(w+1,i,y-i);
}
}
int main()
{
scanf("%d",&n);
fac[0]=1;
for(int i=1;i<=n;i++)
fac[i]=fac[i-1]*i%mod;
dfs(1,1,n);
printf("%d\n",ans*ksm(fac[n],mod-2)%mod);
return 0;
}