HDU 2157 How many ways??:矩阵快速幂【i到j共经过k个节点的方法数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2157

题解:

  给你一个有向图,n个节点m条边,问你从i到j共经过k个节点的方法数(不算i点)。

题解:

  先用邻接矩阵存图。

  假设k = 2,那么从i到j的方法数 = ∑ way[i][x] * way[x][j] (0<=x<n && x!=i && x!=j)

  诶?快看,那是矩阵乘法!

  

  设邻接矩阵为A,若i到j有边则val[i][j] = 1。

  k = 2时答案矩阵ans是A^2,答案就是ans.val[i][j]。

  那k任意时,答案矩阵就是A^k,答案为ans.val[i][j]。

AC Code:

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <string.h>
  4 #define MAX_L 25
  5 #define MOD 1000
  6
  7 using namespace std;
  8
  9 struct Mat
 10 {
 11     int n;
 12     int m;
 13     int val[MAX_L][MAX_L];
 14     Mat()
 15     {
 16         n=0;
 17         m=0;
 18         memset(val,0,sizeof(val));
 19     }
 20 };
 21
 22 int n,m,t;
 23 int a,b,k;
 24
 25 Mat make_unit(int n)
 26 {
 27     Mat mat;
 28     mat.n=n;
 29     mat.m=n;
 30     for(int i=0;i<n;i++)
 31     {
 32         mat.val[i][i]=1;
 33     }
 34     return mat;
 35 }
 36
 37 Mat mul_mat(const Mat &a,const Mat &b)
 38 {
 39     Mat c;
 40     if(a.m!=b.n)
 41     {
 42         cout<<"Error: mul_mat"<<endl;
 43         return c;
 44     }
 45     c.n=a.n;
 46     c.m=b.m;
 47     for(int i=0;i<a.n;i++)
 48     {
 49         for(int j=0;j<b.m;j++)
 50         {
 51             for(int k=0;k<a.m;k++)
 52             {
 53                 c.val[i][j]+=a.val[i][k]*b.val[k][j];
 54                 c.val[i][j]%=MOD;
 55             }
 56         }
 57     }
 58     return c;
 59 }
 60
 61 Mat quick_pow_mat(Mat mat,int k)
 62 {
 63     Mat ans;
 64     if(mat.n!=mat.m)
 65     {
 66         cout<<"Error: quick_pow_mat"<<endl;
 67         return ans;
 68     }
 69     ans=make_unit(mat.n);
 70     while(k)
 71     {
 72         if(k&1)
 73         {
 74             ans=mul_mat(ans,mat);
 75         }
 76         mat=mul_mat(mat,mat);
 77         k>>=1;
 78     }
 79     return ans;
 80 }
 81
 82 int main()
 83 {
 84     while(cin>>n>>m)
 85     {
 86         if(n==0 && m==0) break;
 87         Mat start;
 88         start.n=n;
 89         start.m=n;
 90         for(int i=0;i<m;i++)
 91         {
 92             cin>>a>>b;
 93             start.val[a][b]=1;
 94         }
 95         cin>>t;
 96         for(int i=0;i<t;i++)
 97         {
 98             cin>>a>>b>>k;
 99             Mat ans=quick_pow_mat(start,k);
100             cout<<ans.val[a][b]<<endl;
101         }
102     }
103 }
时间: 2024-10-23 04:18:39

HDU 2157 How many ways??:矩阵快速幂【i到j共经过k个节点的方法数】的相关文章

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

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

HDU 4896 Minimal Spanning Tree(矩阵快速幂)

题意: 给你一幅这样子生成的图,求最小生成树的边权和. 思路:对于i >= 6的点连回去的5条边,打表知907^53 mod 2333333 = 1,所以x的循环节长度为54,所以9个点为一个循环,接下来的9个点连回去的边都是一样的.预处理出5个点的所有连通状态,总共只有52种,然后对于新增加一个点和前面点的连边状态可以处理出所有状态的转移.然后转移矩阵可以处理出来了,快速幂一下就可以了,对于普通的矩阵乘法是sigma( a(i, k) * b(k, j) ) (1<=k<=N), 现在

HDU - 1588 Gauss Fibonacci (矩阵快速幂+二分求等比数列和)

Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r a very clever boy. So if you wanna me be your GF, you should solve the problem called GF~. " How good an opportunity that Gardon can not give up! The "Prob

hdu 1588 Gauss Fibonacci(矩阵快速幂)

Gauss Fibonacci Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2090    Accepted Submission(s): 903 Problem Description Without expecting, Angel replied quickly.She says: "I'v heard that you'r

hdu 4965 Fast Matrix Calculation(矩阵快速幂)

题目链接:hdu 4965 Fast Matrix Calculation 题目大意:给定两个矩阵A,B,分别为N*K和K*N: 矩阵C = A*B 矩阵M=CN?N 将矩阵M中的所有元素取模6,得到新矩阵M' 计算矩阵M'中所有元素的和 解题思路:因为矩阵C为N*N的矩阵,N最大为1000,就算用快速幂也超时,但是因为C = A*B, 所以CN?N=ABAB-AB=AC′N?N?1B,C' = B*A, 为K*K的矩阵,K最大为6,完全可以接受. #include <cstdio> #inc

HDU 2294 Pendant (DP+矩阵快速幂降维)

HDU 2294 Pendant (DP+矩阵快速幂降维) ACM 题目地址:HDU 2294 Pendant 题意: 土豪给妹子做首饰,他有K种珍珠,每种N个,为了炫富,他每种珍珠都要用上.问他能做几种长度[1,N]的首饰. 分析: 1 ≤ N ≤ 1,000,000,000简直可怕. 首先想dp,很明显可以想到: dp[i][j] = (k-(j-1))*dp[i-1][j-1] + j*dp[i-1][j](dp[i][j]表示长度为i的并且有j种珍珠的垂饰有多少个) 然后遇到N太大的话,

HDU 1588 Gauss Fibonacci(矩阵快速幂+二分等比序列求和)

HDU 1588 Gauss Fibonacci(矩阵快速幂+二分等比序列求和) ACM 题目地址:HDU 1588 Gauss Fibonacci 题意: g(i)=k*i+b;i为变量. 给出k,b,n,M,问( f(g(0)) + f(g(1)) + ... + f(g(n)) ) % M的值. 分析: 把斐波那契的矩阵带进去,会发现这个是个等比序列. 推倒: S(g(i)) = F(b) + F(b+k) + F(b+2k) + .... + F(b+nk) // 设 A = {1,1,

HDU 4965 Fast Matrix Calculation (矩阵快速幂取模----矩阵相乘满足结合律)

http://acm.hdu.edu.cn/showproblem.php?pid=4965 利用相乘的可结合性先算B*A,得到6*6的矩阵,利用矩阵快速幂取模即可水过. 1 #include<iostream> 2 #include<stdio.h> 3 #include<iostream> 4 #include<stdio.h> 5 #define N 1010 6 #define M 1010 7 #define K 6 8 using namespa

HDU 1575 Tr A(矩阵快速幂)

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5537    Accepted Submission(s): 4161 Problem Description A为一个方阵,则Tr A表示A的迹(就是主对角线上各项的和),现要求Tr(A^k)%9973. Input 数据的第一行是一个T,表示有T组数据.每组数据的第一行有n(2 <=