1. 程式人生 > >[HNOI2009]圖的同構

[HNOI2009]圖的同構

gcd desc str com ret 整數 tps tro body

Description

求兩兩互不同構的含n個點的簡單圖有多少種。

簡單圖是關聯一對頂點的無向邊不多於一條的不含自環的圖。

a圖與b圖被認為是同構的是指a圖的頂點經過一定的重新標號以後,a圖的頂點集和邊集能完全與b圖一一對應。

Input

輸入一行一個整數N,表示圖的頂點數,0<=N<=60

Output

輸出一行一個整數表示含N個點的圖在同構意義下互不同構的圖的數目,答案對997取模。

Sample Input

輸入1
1

輸入2
2

輸入3
3

Sample Output

輸出1
1

輸出2
2

輸出3
4
https://www.cnblogs.com/gengchen/p/6390122.html http://blog.csdn.net/wzq_qwq/article/details/48035455 https://wenku.baidu.com/view/8a99ebfdc8d376eeaeaa31a9.html 群論入門中
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
6 typedef long long lol; 7 int Mod=997; 8 lol n,A[1001],ans,fac[1001],cnt,num[10001],p[1001]; 9 int gcd(int a,int b) 10 { 11 if (b==0) 12 return a; 13 return gcd(b,a%b); 14 } 15 lol qpow(lol x,lol y) 16 { 17 lol res=1; 18 while (y) 19 { 20 if (y&1) res=(res*x)%Mod; 21
x=(x*x)%Mod; 22 y/=2; 23 } 24 return res; 25 } 26 void dfs(int now,int left) 27 {int i,j; 28 lol sum1=0,sum2=1; 29 if (left==0) 30 { 31 for (i=1;i<=cnt;i++) 32 { 33 sum1+=((num[i]-1)*num[i]/2)*p[i]+p[i]/2*num[i]; 34 for (j=i+1;j<=cnt;j++) 35 sum1+=num[i]*num[j]*gcd(p[i],p[j]); 36 sum2=sum2*fac[num[i]]*qpow(p[i],num[i])%Mod; 37 } 38 sum2=fac[n]*A[sum2%Mod]; 39 ans=(ans+sum2*qpow(2,sum1)%Mod)%Mod; 40 return; 41 } 42 if (now>left) return; 43 dfs(now+1,left); 44 for (i=1;i*now<=left;i++) 45 { 46 cnt++; 47 p[cnt]=now; 48 num[cnt]=i; 49 dfs(now+1,left-i*now); 50 cnt--; 51 } 52 } 53 int main() 54 {int i; 55 cin>>n; 56 A[1]=1;A[0]=1; 57 for (i=2;i<=996;i++) 58 A[i]=((Mod-Mod/i)*A[Mod%i])%Mod; 59 fac[0]=1; 60 for (i=1;i<=996;i++) 61 fac[i]=(fac[i-1]*i)%Mod; 62 dfs(1,n); 63 for (i=1;i<=n;i++) 64 ans=ans*A[i]%Mod; 65 cout<<ans; 66 }

[HNOI2009]圖的同構