hdu 2157 从a点走到b点刚好k步的方案数是多少 (矩阵快速幂)
2015-05-29 21:10
405 查看
n个点 m条路 询问T次 从a点走到b点刚好k步的方案数是多少
给定一个有向图,问从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条边的路径数
Sample Input
4 4 // n m
0 1
0 2
1 3
2 3
2 //T
0 3 2 //a b k
0 3 3
3 6
0 1
1 0
0 2
2 0
1 2
2 1
2
1 2 1
0 1 3
0 0
Sample Output
2
0
1
3
# include <iostream> # include <cstdio> # include <cstring> # include <algorithm> # include <cmath> # define LL long long using namespace std ; const int MOD = 1000 ; int n ; struct Matrix { LL mat[31][31]; }; Matrix mul(Matrix a,Matrix b) //矩阵乘法 { Matrix c; for(int i=0;i<n;i++) for(int j=0;j<n;j++) { c.mat[i][j]=0; for(int k=0;k<n;k++) { c.mat[i][j]=(c.mat[i][j] + a.mat[i][k]*b.mat[k][j])%MOD; } } return c; } Matrix pow_M(Matrix a,int k) //矩阵快速幂 { Matrix ans; memset(ans.mat,0,sizeof(ans.mat)); for (int i=0;i<n;i++) ans.mat[i][i]=1; Matrix temp=a; while(k) { if(k&1)ans=mul(ans,temp); temp=mul(temp,temp); k>>=1; } return ans; } int main () { //freopen("in.txt","r",stdin) ; int m ; while(cin>>n>>m) { if (n == 0 && m == 0) break ; int i ; Matrix A , B ; int a ,b , k ; memset(A.mat,0,sizeof(A.mat)); for (i = 0 ; i < m ;i++) { cin>>a>>b ; A.mat[a][b] = 1 ; } int T ; cin>>T ; while(T--) { cin>>a>>b>>k ; B = pow_M(A,k) ; cout<<B.mat[a][b]<<endl ; } } return 0 ; }View Code
相关文章推荐
- leetcode 11 -- Container With Most Water
- USACO--3.3A Game+dp
- 关于当前的一点记忆or牢骚
- [Java]交换排序
- leetcode Maximum Gap
- 数字集成电路设计-20-multi-cycle
- 关于错误perhaps the designated entry point is not set的解决方法
- Drbd的概念和安装一
- 盒子模型与定位
- 二叉树的遍历(前序+中序+后序)
- 【转】变色龙启动知识
- import和class关键字的区别
- PhpStorm快捷键设置/个性化设置,如何多项目共存?如何更换主题?
- 黄洁:Intel Spark应用优化和实践经验
- hdu 4291(矩阵快速幂 + 循环节)
- 王爽汇编程序设计练习题
- js查找一篇英文文章中出现频率最高的单词
- 黑马程序员 C语言:循环语句
- CSS命名规则规范整理
- 第一章 笔记