hdu2157 How many ways?

题目大意:给定一个有向图,问从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>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值