题目类型:拆点, 矩阵快速幂
转化为矩阵快速幂,好题!
传送门:>Here<
题意:给出邻接矩阵,求\(1\)到\(N\)恰好长度为\(T\)的路径方案数
解题思路
如果题目给出的是一个\(01\)矩阵,那么直接矩阵快速幂解决。详见How many ways??
然而带权了怎么办?
转化为01矩阵!容易发现题目给出的矩阵权值小于10,因此每个点拆成10个点,顺次连接权值为1的边。然后若\((u,v)\)之间距离为\(d\),那么将\(u\)的第\(d-1\)个点连一条1的边到\(v\)的第一个点。
然后矩阵快速幂解决!
反思
看到这种相似的问题,很有可能用一种巧妙的方法将其转化为已知的经典问题。用矩阵快速幂求解路径方案数实在是经典到不能再经典了,再加上题目输入矩阵的特殊性,拆点就非常自然了。
Code
新的一种矩阵快速幂的写法,用的是一个结构体,让矩阵乘法变为一个函数。这样貌似在做快速幂的时候思路更清晰一些。然而码量增多了……
/*By DennyQi 2018*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 10010;
const int MAXM = 20010;
const int MOD = 2009;
const int INF = 1061109567;
inline int Max(const int a, const int b){ return (a > b) ? a : b; }
inline int Min(const int a, const int b){ return (a < b) ? a : b; }
inline int read(){
int x = 0; int w = 1; register char c = getchar();
for(; c ^ '-' && (c < '0' || c > '9'); c = getchar());
if(c == '-') w = -1, c = getchar();
for(; c >= '0' && c <= '9'; c = getchar()) x = (x<<3) + (x<<1) + c - '0'; return x * w;
}
struct Matrix{
int a[110][110];
inline void clear(){
memset(a, 0, sizeof a);
}
};
int N,T,dis;
Matrix g,ans;
char s[20];
inline Matrix mul(Matrix a, Matrix b){
Matrix res,tmp;
res.clear();
tmp.clear();
for(int i = 1; i <= N*10; ++i){
for(int j = 1; j <= N*10; ++j){
tmp.a[i][j] = 0;
for(int k = 1; k <= N*10; ++k){
tmp.a[i][j] = (tmp.a[i][j] + a.a[i][k] * b.a[k][j]) % MOD;
}
}
}
for(int i = 1; i <= N*10; ++i){
for(int j = 1; j <= N*10; ++j){
res.a[i][j] = tmp.a[i][j];
}
}
return res;
}
inline void quick_power(int y){
while(y > 0){
if(y & 1){
ans = mul(ans, g);
}
y /= 2;
g = mul(g, g);
}
}
int main(){
scanf("%d%d", &N, &T);
for(int i = 1; i <= N; ++i){
for(int j = 1; j < 10; ++j){
g.a[(i-1)*10+j][(i-1)*10+j+1] = 1;
}
}
for(int i = 1; i <= N; ++i){
scanf("%s", s);
for(int j = 0; j < N; ++j){
dis = s[j]-'0';
if(dis > 0){
g.a[(i-1)*10+dis][(j)*10+1] = 1;
}
}
}
for(int i = 1; i <= N*10; ++i) ans.a[i][i] = 1;
quick_power(T);
printf("%d", ans.a[1][(N-1)*10+1] % MOD);
return 0;
}
[SCOI2009] 迷路的更多相关文章
-
BZOJ 1297: [SCOI2009]迷路( dp + 矩阵快速幂 )
递推式很明显...但是要做矩阵乘法就得拆点..我一开始很脑残地对于每一条权值v>1的边都新建v-1个节点去转移...然后就TLE了...把每个点拆成9个就可以了...时间复杂度O((9N)^3* ...
-
1297: [SCOI2009]迷路
1297: [SCOI2009]迷路 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 652 Solved: 442[Submit][Status] ...
-
【矩阵快速幂】bzoj1297 [SCOI2009]迷路
1297: [SCOI2009]迷路 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1407 Solved: 1007[Submit][Status ...
-
[BZOJ 1297][SCOI2009]迷路
1297: [SCOI2009]迷路 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1418 Solved: 1017[Submit][Status ...
-
B20J_1297_[SCOI2009]迷路_矩阵乘法
B20J_1297_[SCOI2009]迷路_矩阵乘法 题意:有向图 N 个节点,从节点 0 出发,必须恰好在 T 时刻到达节点 N-1.总共有多少种不同的路径? 2 <= N <= 10 ...
-
【BZOJ1297】[SCOI2009]迷路(矩阵快速幂)
[BZOJ1297][SCOI2009]迷路(矩阵快速幂) 题面 BZOJ 洛谷 题解 因为边权最大为\(9\),所以记录往前记录\(9\)个单位时间前的.到达每个点的方案数就好了,那么矩阵大小就是\ ...
-
bzoj1297 / P4159 [SCOI2009]迷路
P4159 [SCOI2009]迷路 如果边权只有 0/1 那么不就是一个灰常简单的矩阵快速幂吗! 然鹅边权 $<=9$ 所以我们把每个点拆成9个点! 解决~ #include<iostr ...
-
[Bzoj1297][Scoi2009 ]迷路 (矩阵乘法 + 拆点)
1297: [SCOI2009]迷路 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1385 Solved: 993[Submit][Status] ...
-
BZOJ1297: [SCOI2009]迷路 矩阵快速幂
Description windy在有向图中迷路了. 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1. 现在给出该有向图,你能告诉windy总共有多少种不同 ...
-
1297. [SCOI2009]迷路【矩阵乘法】
Description windy在有向图中迷路了. 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1. 现在给出该有向图,你能告诉windy总共有多少种不同 ...
随机推荐
-
mfc+vtk
MFC中view类主要处理显示视图,doc类处理文档,mainframe主要为整个窗口的和工程的设置管理.由此,VTK与MFC联合编程时,需要主要的是数据操作,以及显示要很好的与MFC中的结构结合,做 ...
-
(3)WebApi客户端调用
1.创建一个应用台控制程序,可以把Model的引用,用下面的方法拖拽上来(解决方案里没有这个文件,只是这个文件的引用) 2.Program.cs using System; using System ...
-
td在relative模式下,IE9不显示border
方法一 .thisTd { background-clip: padding-box; position:relative; } 方法二 .thisTd { z-index=-1; ...
-
iframe框架嵌套技巧(全屏,去双滚动条)
一般情况下我们很少用到iframe(框架),但有些特殊的情况下我们不得不使用iframe,那么或许或遇到嵌套内容不全屏,网页周围有边框,双滚动条等等情况,下面来说一下处理技巧. 全屏与边框处理: &l ...
-
[LeetCode] next_permutation
概念 全排列的生成算法有很多种,有递归遍例,也有循环移位法等等.C++/STL中定义的next_permutation和prev_permutation函数则是非常灵活且高效的一种方法,它被广泛的应用 ...
-
【LeetCode】419. Battleships in a Board
Given an 2D board, count how many different battleships are in it. The battleships are represented w ...
-
查看selinux与关闭方法
查看当前用户selinux 状态 [root@o- ~]# getenforce Disabled [root@o- ~]# setenforce usage: setenforce [ Enforc ...
-
windows server 2008 R2之tomcat开机自启
方法一: 写一个批处理文件autostartup.bat用来启动tomcat,内容如下.复制时不要把复制内容也复制进去 set CATALINA_HOME=C:\apache-tomcat-8.5.3 ...
-
【CF1042D】Petya and Array
题目大意:给定一个 N 个数组成的序列,给定一个 T,求有多少个区间满足\(\sum_{i=l}^ra[i]<T\). 题解:区间和问题可以用前缀和优化,即:求有多少个区间满足\(sum[r]- ...
-
js 拖拽 碰撞 + 重力 运动
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...