HNCPC2019H 有向图

题目
(f_i)表示经过(i)的期望次数。那么显然答案(ans_j=sumlimits_{i=1}^nf_iP_{i,j})
我们可以轻松地列出转移式子:

[f_1=sumlimits_{j=1}^nf_jP_{j,1}+1 ]

[f_i=sumlimits_{j=1}^nf_jP_{j,i} ]

高消即可。

#include<bits/stdc++.h>
using namespace std;
const int N=1007,P=1000000007;
int p[N][N],a[N][N];
int inc(int a,int b){a+=b;return a>=P? a-P:a;}
int mns(int a,int b){a-=b;return a<0? a+P:a;}
int mul(int a,int b){return 1ll*a*b%P;}
int inv(int a){int r=1,k=P-2;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;}
int read(){int x;cin>>x;return x;}
int main()
{
    freopen("1.in","r",stdin);
    int n,m,i,j,k,x,ans,Inv=inv(10000);
    while(scanf("%d%d",&n,&m)!=EOF)
    {
	memset(a,0,sizeof a);
	for(i=1;i<=n;++i) for(j=1;j<=n+m;++j) p[i][j]=mul(read(),Inv);
	for(i=1;i<=n;++i)
        {
            for(j=1;j<=n;++j) a[i][j]=i==j? mns(p[j][i],1):p[j][i];
	    a[i][n+1]=i==1? P-1:0;
        }
	for(i=1;i<=n;++i) for(j=1;j<=n;++j) if(i^j) for(x=mul(a[j][i],inv(a[i][i])),k=1;k<=n+1;++k) a[j][k]=mns(a[j][k],mul(a[i][k],x));
	for(i=1;i<=n;++i) a[i][n+1]=mul(a[i][n+1],inv(a[i][i]));
	for(i=n+1;i<=n+m;++i)
        {
            for(ans=0,j=1;j<=n;++j) ans=inc(ans,mul(p[j][i],a[j][n+1]));
            printf("%d ",ans);
        }
        puts("");
    }
}
原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/11725337.html