P8633 题解
题意:就对于一个有
其中,两种染色方式相同称为对其中一个图的所有点重编号之后,两个图同构且对应点颜色相同。
考虑使用 Polya 定理,那么我们就需要找到所有置换,满足对点进行置换之后图仍然同构。
比如说,对于样例来说,所有满足条件的置换为
由于
找到置换群
总体复杂度为
由于时限宽松,这里给出一个较劣的
#include <bits/stdc++.h>
#define Mod 10007
using namespace std;
int Qread()
{
int x=0;char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return x;
}
long long qpow(long long a,long long p)
{
long long ret=1;
for(;p;p>>=1,a=a*a%Mod)
if(p&1) ret=ret*a%Mod;
return ret;
}
int n,m,k,u,v;
long long ans,cnt;
bool ed[20][20];
int p[20];bool vis[20];
bool chk()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(ed[i][j]^ed[p[i]][p[j]])
return false;
return true;
}
int get_cir()
{
int ret=0,nw;
for(int i=1;i<=n;i++) vis[i]=false;
for(int i=1;i<=n;i++)
{
if(vis[i]) continue;
nw=i;
do vis[nw]=true,nw=p[nw];
while(nw!=i);
ret++;
}
return ret;
}
int main()
{
n=Qread(),m=Qread(),k=Qread();
for(int i=1;i<=n;i++)
p[i]=i;
for(int i=1;i<=m;i++)
{
u=Qread(),v=Qread();
ed[u][v]=ed[v][u]=true;
}
do
{
if(!chk()) continue;
cnt++;
ans=(ans+qpow(k,get_cir()))%Mod;
}while(next_permutation(p+1,p+n+1));
printf("%d\n",ans*qpow(cnt,Mod-2)%Mod);
return 0;
}