JZOJ 3085. 图的计数
题目
分析
- 首先,我们可以看到在这个n个点m条边的有向图中,最短路径是n-1
- 那么我们已经确定了n-1条边,剩下的边肯定不能使最短路径变得更短
- 简单点来说,就是剩下的边不能在n-1最短路径上的边里两两连边,这样的话方案数就很容易算出来了,C(n-1,2)=(n-1)(n-2)/2
- 那么我们就可以把剩下的m-n+1条边随便放入图中,那么就有N*N-C(n-1,2)的一种情况
- 就相当与把n个球放入m个挡板中C(n-m+1,n)
- 答案就是C(n*n-C(n-1,2)-1+m-(n-1),m-(n-1))
- 使用逆元推 m-(n-1)次。最后再乘以(n-2)!,就是答案了。时间复杂度为 O(MlogN+N)
代码
#include<cstdio> const int md=1000000007; long long n,m; long long qsm(long long x,long long t){ long long s=1; while (t>0){ if (t%2==1) s=s*x%md; x=x*x%md; t=t/2; } return s; } long long g(long long b,long long d){ long long v=1; for (int i=1;i<=d;i++)v=(b-i+1)*v%md*qsm(i,md-2)%md; for (int i=1;i<=n-2;i++)v=v*i%md; return v; } int main(){ scanf("%lld%lld",&n,&m); printf("%lld",g(n*n-(n-1)*(n-2)/2+m-n,m-n+1)); return 0; }
为何要逼自己长大,去闯不该闯的荒唐