给定一个有向图,问从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;
}