查看原题
点击跳转
为每个连通块点数
对每个连通块构建prufer
序列
由于度数为边数两倍,
对于给定
序列构造prufer
序列的方案数为:
对于第
个连通块,它的连接方式有
种,对于给定
序列使图连通的方案数为:
枚举
序列:
换元,设
:
根据多元二项式定理:
原式化简得:
即
#include<bits/stdc++.h>
const int N=100011;
int n,m,p,f[N],s[N];
int gf(int x){return x==f[x]?x:f[x]=gf(f[x]);}
int pw(int x,int b){
int res=1;
for(;b;b>>=1,x=1ll*x*x%p)
if(b&1)res=1ll*res*x%p;
return res;
}
int main(){
scanf("%d%d%d",&n,&m,&p);
if(p==1)return puts("0"),0;
int x,y,ans=1,k=0;
for(int i=1;i<=n;++i)f[i]=i;
for(int i=1;i<=m;++i)
scanf("%d%d",&x,&y),f[gf(x)]=gf(y);
for(int i=1;i<=n;++i)++s[gf(i)];
for(int i=1;i<=n;++i)
if(i==f[i])ans=1ll*ans*s[i]%p,++k;
if(k==1)puts("1");
else printf("%d\n",1ll*pw(n,k-2)*ans%p);
}