码迷,mamicode.com
首页 > 其他好文 > 详细

P4159 [SCOI2009]迷路

时间:2018-11-05 11:34:25      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:https   std   iostream   传送门   title   char   print   getchar   tor   

传送门

先考虑只有 01 边权的情况

显然可以DP+矩阵加速

但是现在边权不止 1

然鹅最大也只有 9

所以从这里入手,把点拆成 9 个,然后点之间的边权也就可以变成 1 了

同样的转移和矩阵加速

注意点之间的连接关系

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<0||ch>9) { if(ch==-) f=-1; ch=getchar(); }
    while(ch>=0&&ch<=9) { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=207,mo=2009;
inline int fk(int x) { return x>=mo ? x-mo : x; }
int n,T,m;
struct matrix//矩阵乘法不解释
{
    int a[N][N];
    matrix () { memset(a,0,sizeof(a)); }
    inline matrix operator * (const matrix &tmp) const {
        matrix res;
        for(int i=1;i<=m;i++)
            for(int j=1;j<=m;j++)
                for(int k=1;k<=m;k++)
                    res.a[i][j]=fk(res.a[i][j]+a[i][k]*tmp.a[k][j]%mo);
        return res;
    }
}F,M;
matrix ksm(matrix X,int Y)//矩阵快速幂不解释
{
    matrix res;
    for(int i=1;i<=m;i++) res.a[i][i]=1;
    while(Y)
    {
        if(Y&1) res=res*X;
        X=X*X; Y>>=1;
    }
    return res;
}
char s[N];
int main()
{
    n=read(); T=read(); m=n*9;
    for(int i=1;i<=n;i++)//构造转移矩阵
    {
        int t=(i-1)*9+1;
        for(int j=1;j<9;j++) M.a[t+j][t+j-1]=1;
        scanf("%s",s+1);
        for(int j=1;j<=n;j++)
        {
            if(s[j]==0) continue;
            M.a[t][(j-1)*9+s[j]-0]=1;
        }
    }
    F.a[1][1]=1;
    F=F*ksm(M,T);
    printf("%d",F.a[1][(n-1)*9+1]);
    return 0;
}

 

P4159 [SCOI2009]迷路

标签:https   std   iostream   传送门   title   char   print   getchar   tor   

原文地址:https://www.cnblogs.com/LLTYYC/p/9907672.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!