HDU 2157 How many ways?? 矩阵

可达矩阵的K次幂便是从i到j走K步能到达的方案数。

注意处理k=0的情况。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <climits>
#include <iostream>
#include <string>

using namespace std;

#define MP make_pair
#define PB push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
const int INF = INT_MAX / 3;
const double eps = 1e-8;
const LL LINF = 1e17;
const double DINF = 1e60;
const int maxn = 30;
const int mod = 1000;

struct Matrix {
    int n, m, data[maxn][maxn];
    Matrix(int n = 0, int m = 0): n(n), m(m) {
        memset(data, 0, sizeof(data));
    }
};

Matrix operator * (Matrix a, Matrix b) {
    Matrix ret(a.n, b.m);
    for(int i = 1; i <= a.n; i++) {
        for(int j = 1; j <= b.m; j++) {
            for(int k = 1; k <= a.m; k++) {
                ret.data[i][j] += a.data[i][k] * b.data[k][j];
                ret.data[i][j] %= mod;
            }
        }
    }
    return ret;
}

Matrix pow(Matrix mat, int p) {
    if(p == 0) {
        Matrix ret(mat.n, mat.m);
        for(int i = 1; i <= mat.n; i++)  ret.data[i][i] = 1;
        return ret;
    }
    if(p == 1) return mat;
    Matrix ret = pow(mat * mat, p / 2);
    if(p & 1) ret = ret * mat;
    return ret;
}

int n, m;

int main() {
    while(scanf("%d%d", &n, &m), n) {
        Matrix mat(n, n);
        for(int i = 1; i <= m; i++) {
            int a, b; scanf("%d%d", &a, &b);
            mat.data[a + 1][b + 1] = 1;
        }
        int Q; scanf("%d", &Q);
        while(Q--) {
            int a, b, k; scanf("%d%d%d", &a, &b, &k);
            Matrix ret = pow(mat, k);
            printf("%d\n", ret.data[a + 1][b + 1]);
        }
    }
    return 0;
}

  

时间: 2024-10-15 19:29:39

HDU 2157 How many ways?? 矩阵的相关文章

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 2157 How many ways??

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2157 题目大意:给定一个有向图,问从A点恰好走k步(允许重复经过边)到达B点的方案数mod p的值 本来以为是DFS搜索,发现用矩阵也可以做!~ 好神奇. 把 给定的图转为邻接矩阵,即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

HDU 2157 How many ways?? 【矩阵经典8】

任意门:http://acm.hdu.edu.cn/showproblem.php?pid=2157 How many ways?? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5339    Accepted Submission(s): 2109 Problem Description 春天到了, HDU校园里开满了花, 姹紫嫣红

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时答案矩

HDU 2157 How many ways?? 关系矩阵+快速幂

Problem Description 春天到了, HDU校园里开满了花, 姹紫嫣红, 非常美丽. 葱头是个爱花的人, 看着校花校草竞相开放, 漫步校园, 心情也变得舒畅. 为了多看看这迷人的校园, 葱头决定, 每次上课都走不同的路线去教室, 但是由于时间问题, 每次只能经过k个地方, 比方说, 这次葱头决定经过2个地方, 那他可以先去问鼎广场看看喷泉, 再去教室, 也可以先到体育场跑几圈, 再到教室. 他非常想知道, 从A 点恰好经过k个点到达B点的方案数, 当然这个数有可能非常大, 所以你只

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 2157 How many ways?? (可达矩阵)

题意:给你一个有向图,从A 点到 B点恰好经过k个点的方案数 (k < 20), 可以走重复边 思路:利用离散数学中的可达矩阵,可达矩阵的K次幂便是从i到j走K步能到达的方案数 代码: #include <cstdio> #include <cstring> #include <iostream> using namespace std; typedef long long ll; int N,M,P; const int MOD=1000; //int MOD;

HDU 2157 How many ways??

矩阵快速幂. 先构造邻接矩阵,这个矩阵的K次方,就表示从从i到j有几种走法. #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int n,m; const int maxn=20; const int MOD=1000; struct Matrix { int A[25][25]; Matrix operator*(Matr

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

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即可.