Link
考虑Prüfer序列,最后剩下两个没删节点之间是有边相连的,所以一定位于二分图的两侧。
因为我们每次是删掉一个点然后将其连着的点加入Prüfer序列,所以Prüfer序列一定是(n-1)个右侧点和(m-1)个左侧点。
稍微模拟一下可以发现,当我们选定了Prüfer序列中出现了哪些点之后,这棵生成树就已经完全确定了,换言之Prüfer序列就只有一种排列方案。
因此总的方案是(n^{m-1}m^{n-1})。
#include<cstdio>
typedef long long i64;
i64 n,m,p;
i64 inc(i64 a,i64 b){return (a+b)%p;}
i64 mul(i64 a,i64 k){i64 r=0;for(;k;k>>=1,a=inc(a,a))if(k&1)r=inc(a,r);return r;}
i64 pow(i64 a,i64 k){i64 r=1;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;}
int main(){scanf("%lld%lld%lld",&n,&m,&p),printf("%lld",mul(pow(n,m-1),pow(m,n-1)));}