题意:
给你一个邻接矩阵,问你从a到b点,可走重复路径,恰好经过k个节点的路径数。
题解:
其实就是一个裸的矩阵快速幂,每走一次,相当于一次乘法。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 #define mst(a,b) memset(a,b,sizeof(a)) 3 #define F(i,a,b) for(int i=a;i<=b;++i) 4 using namespace std; 5 typedef long long ll; 6 7 const int mat_N=21; 8 int mo=1000,n,m; 9 struct mat{ 10 ll c[mat_N][mat_N]; 11 void init(){mst(c,0);} 12 mat operator*(mat b){ 13 mat M;int N=n-1;M.init(); 14 F(i,0,N)F(j,0,N)F(k,0,N)M.c[i][k]=(M.c[i][k]+c[i][j]*b.c[j][k])%mo; 15 return M; 16 } 17 mat operator^(ll k){ 18 mat ans,M=(*this);int N=n-1;ans.init(); 19 F(i,0,N)ans.c[i][i]=1; 20 while(k){if(k&1)ans=ans*M;k>>=1,M=M*M;} 21 return ans; 22 } 23 }A,B; 24 25 int main() 26 { 27 while(scanf("%d%d",&n,&m),n+m) 28 { 29 A.init(); 30 int x,y,t; 31 F(i,1,m) 32 { 33 scanf("%d%d",&x,&y); 34 A.c[x][y]=1; 35 } 36 scanf("%d",&t); 37 while(t--) 38 { 39 int a,b,k; 40 scanf("%d%d%d",&a,&b,&k); 41 B=A^k; 42 printf("%lld ",B.c[a][b]); 43 } 44 } 45 return 0; 46 }