hdu 2157 从a点走到b点刚好k步的方案数是多少 (矩阵快速幂)

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

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cstring>
 4 # include <algorithm>
 5 # include <cmath>
 6 # define LL long long
 7 using namespace std ;
 8
 9 const int MOD = 1000 ;
10 int n ;
11
12 struct Matrix
13 {
14     LL mat[31][31];
15 };
16
17 Matrix mul(Matrix a,Matrix b) //矩阵乘法
18 {
19     Matrix c;
20     for(int i=0;i<n;i++)
21         for(int j=0;j<n;j++)
22         {
23             c.mat[i][j]=0;
24             for(int k=0;k<n;k++)
25             {
26                 c.mat[i][j]=(c.mat[i][j] + a.mat[i][k]*b.mat[k][j])%MOD;
27             }
28         }
29     return c;
30 }
31 Matrix pow_M(Matrix a,int k)  //矩阵快速幂
32 {
33     Matrix ans;
34     memset(ans.mat,0,sizeof(ans.mat));
35     for (int i=0;i<n;i++)
36         ans.mat[i][i]=1;
37     Matrix temp=a;
38     while(k)
39     {
40         if(k&1)ans=mul(ans,temp);
41         temp=mul(temp,temp);
42         k>>=1;
43     }
44     return ans;
45 }
46
47
48 int main ()
49 {
50     //freopen("in.txt","r",stdin) ;
51     int m ;
52     while(cin>>n>>m)
53     {
54         if (n == 0 && m == 0)
55             break ;
56         int i ;
57         Matrix A , B ;
58         int a ,b , k ;
59         memset(A.mat,0,sizeof(A.mat));
60         for (i = 0 ; i < m ;i++)
61         {
62             cin>>a>>b ;
63             A.mat[a][b] = 1 ;
64         }
65         int T ;
66         cin>>T ;
67         while(T--)
68         {
69             cin>>a>>b>>k ;
70             B = pow_M(A,k) ;
71             cout<<B.mat[a][b]<<endl ;
72         }
73     }
74
75     return 0 ;
76 }

时间: 2024-10-22 09:55:06

hdu 2157 从a点走到b点刚好k步的方案数是多少 (矩阵快速幂)的相关文章

hdu 4549 M斐波那契数列(快速幂 矩阵快速幂 费马小定理)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4549: 题目是中文的很容易理解吧.可一开始我把题目看错了,这毛病哈哈. 一开始我看错题时,就用了一个快速幂来解,不用说肯定wa,看题目的通过率也不高,我想会不会有啥坑啊.然而我就是那大坑,哈哈. 不说了,直接说题吧,先讨论k=1,2,3;时的解.这应该会解吧,不多说了: 从第四项开始f(4)=a^1+b^2;f(5)=a^2+b^3;f(6)=a^3+b^5......; 看出来了吧,a上的指数成斐波

HDU 2157 How many ways??(经典矩阵快速幂)

题意:求A经过K个点到B方案数 方法一: 1个0 1 的矩阵 A a[i][j] = 1 表示i 到 j可达 或者说 i 到 j 有1条路 或者说i到j经过一个点的方案数 路可以重复走 而A2 = A* A a[i][j] 的含义是 从i到j经过2个点的方案数 A的k次方 A[i,j]代表 i到j走k步的方案有a[i][j] 矩阵乘法的定义居然和这个模型如此契合,佩服,所以要非常熟悉矩阵乘法的具体步骤才能在这个题目中抽象出矩阵乘法可以正好实现两个定点间的所有可能情况 方法二: 动态规划的思路,状

HDU 5434 Peace small elephant 状压dp+矩阵快速幂

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant Accepts: 38 Submissions: 108 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 小明很喜欢国际象棋,尤其喜欢国际象棋里面的大象(只要无阻挡能够斜着走任意格),但是他觉得国际象棋里的大象太凶残了,于是他

HDU 2254 奥运(矩阵快速幂+二分等比序列求和)

HDU 2254 奥运(矩阵快速幂+二分等比序列求和) ACM 题目地址:HDU 2254 奥运 题意: 中问题不解释. 分析: 根据floyd的算法,矩阵的k次方表示这个矩阵走了k步. 所以k天后就算矩阵的k次方. 这样就变成:初始矩阵的^[t1,t2]这个区间内的v[v1][v2]的和. 所以就是二分等比序列求和上场的时候了. 跟HDU 1588 Gauss Fibonacci的算法一样. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * B

HDU 5318 The Goddess Of The Moon (矩阵快速幂)

题目链接:HDU 5318 The Goddess Of The Moon 题意:给出N串字符串,若是一个字符串的后缀与另一个字符串的前缀相同并且长度大于1,就表示这两个字符串是可以相连的,问M个字符串相连不同方案数为多少. 思路: 1.将输入的字符串预处理存入一个矩阵中,mp[i][j]=1说明str[i]与str[j]能相连,反之,则不能相连. 2.str[i]与str[j]能相连 转化为 i点到j点可达,那么就可以得到一个有向图,长度为M的意思就是 两点之间所走的步数为M的不同走法有多少种

hdu 5411 CRB and Puzzle (矩阵快速幂优化dp)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5411 题意:按题目转化的意思是,给定N和M,再给出一些边(u,v)表示u和v是连通的,问走0,1,2.....M步的方案数. 分析:这题和 hdu5318 The Goddess Of The Moon差不多,就是多了一个等比数列求和. 代码: #include <cstdio> #include <iostream> #include <cstring> using name

HDOJ How many ways?? 2157【矩阵快速幂】

How many ways?? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2046    Accepted Submission(s): 758 Problem Description 春天到了, HDU校园里开满了花, 姹紫嫣红, 非常美丽. 葱头是个爱花的人, 看着校花校草竞相开放, 漫步校园, 心情也变得舒畅. 为了多看看这

HDU 4990 Reading comprehension(找规律+矩阵快速幂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4990 Problem Description Read the program below carefully then answer the question. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include<iostream> #include

HDU 5950 Recursive sequence 矩阵快速幂

http://acm.hdu.edu.cn/showproblem.php?pid=5950 一开始以为i^4不能矩阵快速幂,但是结论是可以得,那么要怎么递推呢? 矩阵快速幂的思路都是一样的,matrix_a * matrix_b ^ n 其中,想要维护什么,就在matrix_a写,比如现在是F[n - 1], F[n - 2],我想要递推到下一项,那么就 会变成F[n], F[n - 1],这个时候,你就要寻找一下F[n]和F[n - 1]有什么关系. i^4也一样,想要从i^4 递推到 (i