hdu2157 How many ways?
2016-04-13 09:04
302 查看
题目大意:给定一个有向图,问从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 <bits/stdc++.h> using namespace std; #define MOD 1000 struct matrix { int mat[31][31]; matrix(){memset(mat,0,sizeof(mat));} }; int n; matrix mul(matrix A,matrix B) { matrix C; for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) for(int k = 1; k <= n; k ++) C.mat[i][j] = (C.mat[i][j] + A.mat[i][k] * B.mat[k][j]) % MOD; return C; } matrix powmul(matrix A,int k) { matrix B; for(int i = 1; i <= n; i ++) B.mat[i][i] = 1; while(k) { if(k & 1) B = mul(B,A); A = mul(A,A); k >>= 1; } return B; } int main() { int s,t,m,T,a,b,k; while(~scanf("%d%d",&n,&m)&&(n||m)) { matrix A,B; while(m --) { scanf("%d%d",&s,&t); A.mat[s + 1][t + 1] = 1; } scanf("%d",&T); while(T --) { scanf("%d%d%d",&a,&b,&k); B = A; B = powmul(A,k); cout << B.mat[a + 1][b + 1]<<endl; } } return 0; }</span>
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- Lua和C语言的交互详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总
- C语言中计算正弦的相关函数总结
- 使用C语言详解霍夫曼树数据结构
- C语言实现选择排序、冒泡排序和快速排序的代码示例
- 探讨C语言的那些小秘密之断言
- C语言实现BMP转换JPG的方法
- 深入探讨C语言中局部变量与全局变量在内存中的存放位置