给出一个有向图,判断 从 1 到 n 长度 为 k 的路径有几条
思路 邻接矩阵A^k 次幂,k=1 即 从 顶点 vi 到 vj 长度为 1的路径 有 A[i][j]条。。。
因为 k 很大,如果 直接暴力算 会超时,可采用 二分快速幂求解
假设 A^13
(13)10==(1101)2
那么 A^13==A^8*A^4*A^1
碰到 为 该位为 1 的 就将 A*(A的对应权重次幂),为 0 就 将权重 ^2
#include<iostream>
#include<cstdio>
using namespace std;
typedef int LL;
const int maxn=102;
LL N,M,K,mod=10000;
struct Mat{
LL mt[maxn][maxn];
};
Mat res,tmp,A;
Mat MatMul(Mat a,Mat b){
Mat c;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
c.mt[i][j]=0;
for(int k=0;k<N;k++){
c.mt[i][j]+=(a.mt[i][k]*b.mt[k][j])%mod;
c.mt[i][j]%=mod;
}
}
}
return c;
}
Mat MatFun(Mat a,LL k){
tmp=a;
a=res;
while(k){
if(k&1)a=MatMul(a,tmp);
tmp=MatMul(tmp,tmp);
k>>=1;
}
return a;
}
void getRes(){
for(int i=0;i<N;i++)res.mt[i][i]=1;
}
int main(){
while(scanf("%d%d%d",&N,&M,&K)==3){
memset(A.mt,0,sizeof(A.mt));
memset(res.mt,0,sizeof(res.mt));
int x,y;
while(M--){
scanf("%d%d",&x,&y);
A.mt[x-1][y-1]=1;
}
getRes();
A=MatFun(A,K);
printf("%d\n",A.mt[0][N-1]);
//for(int i=0;i<N;i++){
// for(int j=0;j<N;j++)printf("%d",A.mt[i][j]);
// puts("");
//}
}
return 0;
}