矩阵经典题目八:hdu 2175 How many ways??

来源:互联网 发布:淘宝直邮是真的吗 编辑:程序博客网 时间:2024/06/05 05:28

http://acm.hdu.edu.cn/showproblem.php?pid=2157


给定一个有向图,问从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 <stdio.h>#include <iostream>#include <map>#include <set>#include <list>#include <stack>#include <vector>#include <math.h>#include <string.h>#include <queue>#include <string>#include <stdlib.h>#include <algorithm>#define LL long long#define _LL __int64#define eps 1e-12#define PI acos(-1.0)#define C 240#define S 20using namespace std;const int maxn = 25;const int mod = 1000;int n;struct matrix{int mat[maxn][maxn];void init(){memset(mat,0,sizeof(mat));for(int i = 0; i < maxn; i++)mat[i][i] = 1;}}a;matrix mul(matrix a, matrix b){matrix ans;memset(ans.mat,0,sizeof(ans.mat));for(int i = 0; i < n; i++){for(int k = 0; k < n; k++){if(a.mat[i][k] == 0) continue;for(int j = 0; j < n; j++){ans.mat[i][j] += a.mat[i][k] * b.mat[k][j]%mod;ans.mat[i][j] %= mod;}}}return ans;}matrix pow(matrix a, int n){matrix ans;ans.init();while(n){if(n&1)ans = mul(ans,a);a = mul(a,a);n >>= 1;}return ans;}int main(){int m,T,u,v,k;while(~scanf("%d %d",&n,&m)){if(n == 0 && m == 0) break;memset(a.mat,0,sizeof(a.mat));while(m--){scanf("%d %d",&u,&v);a.mat[u][v] = 1;}scanf("%d",&T);while(T--){scanf("%d %d %d",&u,&v,&k);matrix ans = pow(a,k);printf("%d\n",ans.mat[u][v]);}}return 0;}



0 0