[省选前题目整理][BZOJ 1297]迷路(矩阵快速幂)

来源:互联网 发布:php 伪静态 编辑:程序博客网 时间:2024/04/27 23:37

题目链接

http://www.lydsy.com/JudgeOnline/problem.php?id=1297

思路

比较简单的一个矩阵快速幂的题。。。。
把每个点拆成9个点,分别代表时间1~9的状态,点i到j要t分钟,就从i的第t个状态的点向j的第1个状态的点连边权为1的边,把这个图转化成一个邻接矩阵,自乘T次即可得到答案。

代码

刚开始matrix结构体里的矩阵数组开太大了,局部开一个matrix结构体就RE了真坑爹啊。。。以后记住了

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <algorithm>#define MAXN 100 //!!!!!!#define MOD 2009using namespace std;char s[MAXN];struct Matrix{    int num[MAXN][MAXN];    int n,m;    Matrix()    {        n=m=0;        memset(num,0,sizeof(num));    }}map,one;Matrix operator*(Matrix a,Matrix b){    Matrix c;    c.n=a.n,c.m=b.m;    for(int k=1;k<=a.m;k++)        for(int i=1;i<=c.n;i++)            for(int j=1;j<=c.m;j++)                c.num[i][j]=(c.num[i][j]+a.num[i][k]*b.num[k][j]%MOD)%MOD;    return c;}Matrix fastPow(Matrix base,int pow){    Matrix ans;    ans=one;    while(pow)    {        if(pow&1) ans=ans*base;        base=base*base;        pow>>=1;    }    return ans;}inline int calc(int n,int t){    return (n-1)*9+t;}int main(){    int n,t;    scanf("%d%d",&n,&t);    one.n=one.m=map.n=map.m=calc(n,9);    for(int i=1;i<=calc(n,9);i++)        one.num[i][i]=1;    for(int i=1;i<=n;i++)        for(int j=1;j<=8;j++)            map.num[calc(i,j)][calc(i,j+1)]=1;    for(int i=1;i<=n;i++)    {        scanf("%s",s+1);        for(int j=1;j<=n;j++)            if(s[j]!='0')                map.num[calc(i,s[j]-'0')][calc(j,1)]=1;    }    map=fastPow(map,t);    printf("%d\n",map.num[calc(1,1)][calc(n,1)]);    return 0;}
0 0