图的计数

转:这题里介绍的最短路比较特殊,,这条最短路要遍历全图一遍,我们可以枚举最短路径,而组成最短路径需要N-1条边,一共有(N-2)!条可行的最短路径。

如果已经确定了最短路,我们肯定不会加入“捷径边”,就是让最短路有可能变短的边,一共有条。
于是我们可以把剩下的M-(N-1)条边可以选择成为N*N-种有向边中的一种。于是我们可以使用经典的挡板问题组合:
把N个相同的元素放进M个桶的方案数为
推得答案就是这个组c vxxv合数可以使用杨辉三角推出(期望得分60%),也可以使用逆元推m-(n-1)次。最后再乘以(n-2)!,就是答案了。时间复杂度为O(MlogN+N)可以通过全部数据。期望得分100%

#include<bits/stdc++.h>
#define N 100010
#define P 50010
#define inf 2147483647
#define rint register ll
#define ll long long
#define mod (ll)(1e9+7)
#define mem(a,b) memset(a,b,sizeof (a))
#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;



ll ans,n,m;

ll a,b,c,f[N],finv[N];

ll sqr(ll x)
{	return x*x%mod;}

ll power(ll x,ll p)
{
	if(p==0)return 1;
	if(p&1) return x*sqr(power(x,p/2))%mod; else return sqr(power(x,p/2))%mod;
}

ll inv (ll x)
{return power(x%mod,mod-2);}

ll fact(ll x)
{
	ll ans=1;
	for(rint i=1;i<=x;i++)ans=ans*i%mod;
	return ans;
}

ll C(ll n,ll m)
{
	ll a=1,b=0;
	for(rint i=m+1;i<=n;i++)a=a*i%mod;
	b= fact(n-m) %mod; 
	return a*inv(b)%mod;
}

ll db(ll n,ll m)//n分成m份的方案数 
{
		return C(n+m-1 , m);
}

int main()
{
	open("pg");
	scanf("%lld%lld",&n,&m);
	ans= db(n*n - (n-1)*(n-2)/2 , m-(n-1)) * fact(n-2) %mod;
	printf("%lld",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值