bzoj1297: [SCOI2009]迷路 矩阵乘法

本文探讨了在图论中使用快速幂和矩阵的方法来解决特定问题,通过拆点技巧,实现路径计数并优化计算效率。具体介绍了算法实现细节,包括建边规则和矩阵操作,适用于路径长度不超过10的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

拆点。然后快速幂+矩阵。

同一个图走k次所得的解即为答案,由于路程所耗时间<10所以我们可以直接拆点。

把每个点拆为1~9个时刻。建边的时候要注意如果A->B要i分钟,那么应该在A的第i分钟和B的第1分钟连边,不然不好统计最后的解。

“1”矩阵每个点的第i时刻应该和第i+1时刻连一条边,不然快速幂中当前时刻的答案数无法被完全更新。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define mod 2009
struct matrix
{
    int s[110][110];
    int n;
    void init(int k)
    {
        n=k;
        memset(s,0,sizeof(s));
    }
};
matrix operator *(matrix x,matrix y)
{
    matrix c;
    c.init(x.n);
    for(int i=1;i<=c.n;i++)
    {
        for(int j=1;j<=c.n;j++)
        {
            for(int k=1;k<=c.n;k++)
            {
                c.s[i][j]+=x.s[i][k]*y.s[k][j];
                c.s[i][j]%=mod;
            }
        }
    }
    return c;
}
matrix solve(matrix A,int k)
{
    matrix res;
    res.init(A.n);
    for(int i=1;i<=A.n;i++)
    {
        res.s[i][i]=1;
    }
    while(k)
    {
        if(k&1)
            res=res*A;
        k>>=1;
        A=A*A;
    }
    return res;
}
int n,T;
char st[50];
int main()
{
    scanf("%d%d",&n,&T);
    matrix org;
    org.init(n*9);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=8;j++)
        {
            org.s[(i-1)*9+j][(i-1)*9+j+1]=1;
        }
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%s",st+1);
        for(int j=1;j<=n;j++)
        {
            if(st[j]>'0')
            {
                org.s[(i-1)*9+st[j]-'0'][(j-1)*9+1]=1;
            }
        }
    }
    matrix ans;
    ans=solve(org,T);
    printf("%d\n",ans.s[1][n*9-8]);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值