题目

windy在有向图中迷路了。 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1。 现在给出该有向图,你能告诉windy总共有多少种不同的路径吗? 注意:windy不能在某个节点逗留,且通过某有向边的时间严格为给定的时间。

输入格式

第一行包含两个整数,N T。 接下来有 N 行,每行一个长度为 N 的字符串。 第i行第j列为'0'表示从节点i到节点j没有边。 为'1'到'9'表示从节点i到节点j需要耗费的时间。

输出格式

包含一个整数,可能的路径数,这个数可能很大,只需输出这个数除以2009的余数。

输入样例

5 30

12045

07105

47805

12024

12345

输出样例

852

提示

30%的数据,满足 2 <= N <= 5 ; 1 <= T <= 30 。 100%的数据,满足 2 <= N <= 10 ; 1 <= T <= 1000000000 。

题解

设\(f[i][t]\)表示\(t\)时刻到达\(i\)号点的方案数

那么有

\[f[i][t] = \sum\limits_{e(j,i) \in edge} f[j][t - e.w]
\]

\(T\)很大,而且显然这是一个齐次式,考虑矩阵优化

但是矩阵优化只能一层层递推,这里边权的限制使我们可能跨多层

发现边权很小,考虑拆点

每个点拆成一长条链,分别管辖各种权值的出边

这样就可以矩阵优化了

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 95,maxm = 100005,INF = 1000000000,P = 2009;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
struct Matrix{
int s[maxn][maxn],n,m;
Matrix(){n = m = 0; memset(s,0,sizeof(s));}
}F,A;
inline Matrix operator *(const Matrix& a,const Matrix& b){
Matrix ans;
if (a.m != b.n) return ans;
ans.n = a.n; ans.m = b.m;
for (int i = 1; i <= ans.n; i++)
for (int j = 1; j <= ans.m; j++)
for (int k = 1; k <= a.m; k++)
ans.s[i][j] = (ans.s[i][j] + a.s[i][k] * b.s[k][j] % P) % P;
return ans;
}
inline Matrix operator ^(Matrix a,int b){
Matrix ans; ans.n = ans.m = a.n;
REP(i,ans.n) ans.s[i][i] = 1;
for (; b; b >>= 1,a = a * a)
if (b & 1) ans = ans * a;
return ans;
}
int n,T;
char s[maxn];
int main(){
n = read(); T = read();
A.n = A.m = 9 * n;
REP(i,n){
scanf("%s",s + 1);
REP(j,n){
if (s[j] != '0'){
int d = s[j] - '0';
A.s[(j - 1) * 9 + 1][(i - 1) * 9 + d] = 1;
}
}
for (int j = 2; j <= 9; j++)
A.s[(i - 1) * 9 + j][(i - 1) * 9 + j - 1] = 1;
}
F.n = 9 * n; F.m = 1;
F.s[1][1] = 1;
Matrix Ans = (A^T) * F;
printf("%d\n",Ans.s[(n - 1) * 9 + 1][1]);
return 0;
}

BZOJ1297 [SCOI2009]迷路 【矩阵优化dp】的更多相关文章

  1. BZOJ1297 [SCOI2009]迷路 矩阵乘法

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1297 题意概括 有向图有 N 个节点,从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1. ...

  2. BZOJ1297: [SCOI2009]迷路 矩阵快速幂

    Description windy在有向图中迷路了. 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1. 现在给出该有向图,你能告诉windy总共有多少种不同 ...

  3. bzoj1297: [SCOI2009]迷路(矩阵乘法+拆点)

    题目大意:有向图里10个点,点与点之间距离不超过9,问从1刚好走过T距离到达n的方案数. 当时看到这题就想到了某道奶牛题(戳我).这两道题的区别就是奶牛题问的是走T条边,这道题是每条边都有一个边权求走 ...

  4. 矩阵优化dp

    链接:https://www.luogu.org/problemnew/show/P1939 题解: 矩阵优化dp模板题 搞清楚矩阵是怎么乘的构造一下矩阵就很简单了 代码: #include < ...

  5. bzoj 3120 矩阵优化DP

    我的第一道需要程序建矩阵的矩阵优化DP. 题目可以将不同的p分开处理. 对于p==0 || p==1 直接是0或1 对于p>1,就要DP了.这里以p==3为例: 设dp[i][s1][s2][r ...

  6. HDU - 2294: Pendant(矩阵优化DP&前缀和)

    On Saint Valentine's Day, Alex imagined to present a special pendant to his girl friend made by K ki ...

  7. [六省联考2017]组合数问题 (矩阵优化$dp$)

    题目链接 Solution 矩阵优化 \(dp\). 题中给出的式子的意思就是: 求 nk 个物品中选出 mod k 为 r 的个数的物品的方案数. 考虑朴素 \(dp\) ,定义状态 \(f[i][ ...

  8. 2018.10.23 bzoj1297: [SCOI2009]迷路(矩阵快速幂优化dp)

    传送门 矩阵快速幂优化dp简单题. 考虑状态转移方程: f[time][u]=∑f[time−1][v]f[time][u]=\sum f[time-1][v]f[time][u]=∑f[time−1 ...

  9. [Bzoj1297][Scoi2009 ]迷路 (矩阵乘法 + 拆点)

    1297: [SCOI2009]迷路 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1385  Solved: 993[Submit][Status] ...

随机推荐

  1. 多线程程序设计-Thread的一些方法

    run():是程序中会和会和其他线程“同时”执行的部分.   wait():使得当前线程进入等待状态,等待的线程不会主动进入到线程队列中排队等待cpu资源,必须由其他线程调用notify()方法通知它 ...

  2. groups - 显示用户所在的组

    总览 (SYNOPSIS) groups [OPTION]... [USERNAME]... 描述 (DESCRIPTION) --help 显示此帮助, 然后退出 --version 显示版本信息, ...

  3. 四、filter和find函数的区别

    filter(): filter函数会返回data中为true那项的数组(即查询符合条件的数据) eg:data.filter((f)=>{ if(f[name]===item[name]){ ...

  4. 安装搭配VUE使用的UI框架ElementUI

    可以搭配vue的UI框架有几个,我用的是element-ui,现在呢,我要在复习一遍 1.vue init webpack-simple element-ui2.cd element-ui3.npm ...

  5. JavaScript实用的例子

    ---恢复内容开始--- 1.发送验证码 <input id="send" type="button" value="发送验证码"&g ...

  6. 使用jquery.ajax实现省市的二级联动(SSH架构)

    首先实现jquery ajax的二级联动 要下载个jquery.js 我在这里就不准备了 自行百度下载 背景介绍:通过部门的ID来查找部门下的所有班级 我实现二级联动的思路是:先查询所有部门 显示在页 ...

  7. Java基础面试操作题:Java代理工厂设计模式 ProxyFactory 有一个Baby类,有Cry行为,Baby可以配一个保姆 但是作为保姆必须遵守保姆协议:能够处理Baby类Cry的行为,如喂奶、哄睡觉。

    package com.swift; public class Baby_Baomu_ProxyFactory_Test { public static void main(String[] args ...

  8. 创建自定义 Estimator

    ref 本文档介绍了自定义 Estimator.具体而言,本文档介绍了如何创建自定义 Estimator 来模拟预创建的 Estimator DNNClassifier 在解决鸢尾花问题时的行为.要详 ...

  9. Codeforces 517 #A

    http://codeforces.com/contest/1072/problem/A 题目挺简单,就是让你求几个环,占得方格的个数,然而题目为什么给出了公式呢? 然而给出的公式辣么丑,还是不用的好 ...

  10. 【上下界网络流 费用流】bzoj2055: 80人环游世界

    EK费用流居然写错了…… Description     想必大家都看过成龙大哥的<80天环游世界>,里面的紧张刺激的打斗场面一定给你留下了深刻的印象.现在就有这么     一个80人的团 ...