快速矩阵幂-有向图

来源:互联网 发布:钥匙扣淘宝 编辑:程序博客网 时间:2024/05/19 15:19
给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值

把给定的图转为邻接矩阵,即A(i,j)=1当且仅当存在一条边i->j。令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),

实际上就等于从点i到点j恰好经过2条边的路径数(枚举k为中转点)。类似地,C*A的第i行第j列就

表示从i到j经过3条边的路径数。同理,如果要求经过k步的路径数,我们只需要二分求出A^k即可。


代码实现:

/*////////////////////////////////////////////////////////////*/#include <cstdio>#include <cstring>#include <cmath>int n,mod=10000;struct Matrix{    int m[30][30];void clear(){memset(m,0,sizeof(m));}}E, Z;Matrix Mut(Matrix A, Matrix B){    Matrix ans;    for (int i = 0; i<n; i++)        for (int j = 0; j<n; j++)        {            ans.m[i][j] = 0;            for (int k = 0; k<n; k++)            {                ans.m[i][j] += ((A.m[i][k])*(B.m[k][j]));            }        }    return ans;}Matrix Pow(Matrix A, int b){    Matrix t = A, ans = E;    while (b)    {        if (b % 2) ans = Mut(ans, t);        b /= 2;        t = Mut(t, t);    }    return ans;}int main(){    // freopen("in.txt", "r", stdin);Matrix A;int t;while(scanf("%d",&n)!=EOF){//输入邻接矩阵for(int i=0;i<n;i++)for(int j=0;j<n;j++)scanf("%d",&A.m[i][j]);//输入要查找的边,步数int a,b,k; scanf("%d %d %d",&a,&b,&k);E=A;Matrix ans=Pow(A,k-1);printf("%d\n",ans.m[a-1][b-1]);}    return 0;}


0 0
原创粉丝点击