题意:该有向图有 n 个节点,节点从 1至 n 编号,windy 从节点 1 出发,他必须恰好在 t 时刻到达节点 n。现在给出该有向图,你能告诉 windy 总共有多少种不同的路径吗?答案对2009取模。(洛谷 4159)

输入格式:第一行包含两个整数,分别代表 n和 t。第 2 到第 (n + 1)行,每行一个长度为 n 的字符串,第 (i + 1)行的第 j 个字符c [ i ] [ j ]是一个数字字符,若为 0,则代表节点 i 到节点 j 无边,否则代表节点 i 到节点 j 的边的长度为c [ i ] [ j ]。

输出格式:输出一行一个整数代表答案对 2009取模的结果。

数据范围: 2 ≤ n ≤ 10  , 1 ≤ t ≤ 1e9。

分析:首先考虑边权只有  $0,1$ 的情况。令  $f_1=$给定矩阵。因为边权只有  $0,1$,所以我们可以将这个矩阵的意义转化成: $f_t[i][j]=k \Longleftrightarrow$  $i$到 $j$的长度为 $t$的路径条数为 $k$。显然有  $f_t[i][j]=\sum\limits_{k=1}^nf_{t-1}[i][k]\times f_1[k][j]$。

矩阵乘法满足结合律,故  $f_t=f_1^t$。于是这种情况下答案就是  $f_T[1][n]$。考虑边权  $w\in [0,9]\cap\mathbb Z$ 的情况。因为边权可能大于1,所以给定矩阵不能直接转换成那种含义了。但是我们发现  $n\le 10$。这意味着我们可以将每个点都拆开,将这张图转化成边权只有  $0,1$ 的图,这样上面的意义就成立了。

我们发现可以将每个点拆成  $9$ 个点,令有序数对  $(i,j)(i\in [1,n]\cap\mathbb Z,j\in [0,8]\cap\mathbb Z)$ 表示点  $i$ 拆成的第  $j$ 个点,其中第  $0$ 个点是“真”点,其余的是“假”点。我们可以令  $(i,j)(j\in [1,8]\cap\mathbb Z)$ 表示到“真”点  $(i,0)$ 的距离为  $j$ 的“假”点,只要让  $(i,j)(j\in [1,8]\cap\mathbb Z)$ 向  $(i,j-1)$ 连一条边权为  $1$ 的边。这样我们就还原了原图中的边,并且将边权都转化成了  $0,1$。而每个  $(i,j)$ 又可以唯一对应一个编号  $i+j\times n$,因此原矩阵就变成了一个  $9n\times 9n$ 的矩阵  $f_1$。根据前面的推理,同样  $f_t=f_1^t$。答案就是  $f_T[1][n]$。

#include<cstdio>
#include<cstring>
const int mod = 2009; int n,T,m,x; struct Node{
int a[100][100];
Node operator *(const Node &x)const{
Node ans;
memset(ans.a,0,sizeof(ans.a));
for(int i = 1; i <= m; ++i)
for(int t = 1; t <= m; ++t)
for(int k = 1; k <= m; ++k)
ans.a[i][t] = (ans.a[i][t]+a[i][k]*x.a[k][t]) % mod;
return ans;
}
}res,ans; inline int cal(int x,int y){ return x+y*n; } void quick_pow(int k){
ans = res;
while(k){
if(k&1) ans = ans*res;
res = res*res; k >>= 1;
}
} int main(){
scanf("%d%d",&n,&T); m = 9*n;
for(int i = 1; i <= n; ++i){
for(int t = 1; t <= 8; ++t)
res.a[cal(i,t)][cal(i,t-1)] = 1;
for(int t = 1; t <= n; ++t){
scanf("%1d",&x);
if(x) res.a[i][cal(t,x-1)] = 1;
}
}
quick_pow(T-1);
printf("%d",ans.a[1][n]);
return 0;
}

原文链接:https://www.luogu.com.cn/blog/samxiang/solution-p4159

洛谷4159 [SCOI2009] 迷路(矩阵快速幂,拆点)的更多相关文章

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

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

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

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

  3. Luogu P4159 [SCOI2009]迷路 矩阵快速幂+精巧转化

    大致就是矩阵快速幂吧.. 这个时候会发现这些边权$\le 9$,然后瞬间想到上回一道题:是不是可以建一堆转移矩阵再建一个$lcm(1,2,3,4,5,6,7,8,9)$的矩阵?...后来发现十分的慢q ...

  4. 【洛谷 p3390】模板-矩阵快速幂(数论)

    题目:给定n*n的矩阵A,求A^k. 解法:利用矩阵乘法的定义和快速幂解答.注意用负数,但是数据太弱没有卡到我......(P.S.不要在 typedef long long  LL; 前使用 LL. ...

  5. [SCOI2009]迷路(矩阵快速幂) 题解

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

  6. 洛谷 P1226 【模板】快速幂||取余运算

    题目链接 https://www.luogu.org/problemnew/show/P1226 题目描述 输入b,p,k的值,求b^p mod k的值.其中b,p,k*k为长整型数. 输入输出格式 ...

  7. BZOJ 1297 迷路(矩阵快速幂)

    很容易想到记忆化搜索的算法. 令dp[n][T]为到达n点时时间为T的路径条数.则dp[n][T]=sigma(dp[i][T-G[i][n]]); 但是空间复杂度为O(n*T),时间复杂度O(n*n ...

  8. 洛谷P1226 【模板】快速幂||取余运算

    题目描述 输入b,p,k的值,求b^p mod k的值.其中b,p,k*k为长整型数. 输入输出格式 输入格式: 三个整数b,p,k. 输出格式: 输出“b^p mod k=s” s为运算结果 S1: ...

  9. 洛谷P1313 计算系数【快速幂+dp】

    P1313 计算系数 题目描述 给定一个多项式(by+ax)^k,请求出多项式展开后x^n*y^m 项的系数. 输入输出格式 输入格式: 输入文件名为factor.in. 共一行,包含5 个整数,分别 ...

  10. 洛谷——P1226 取余运算||快速幂

    P1226 取余运算||快速幂 题目描述 输入b,p,k的值,求b^p mod k的值.其中b,p,k*k为长整型数. 输入输出格式 输入格式: 三个整数b,p,k. 输出格式: 输出“b^p mod ...

随机推荐

  1. GAN!生成对抗网络GAN全维度介绍与实战

    本文为生成对抗网络GAN的研究者和实践者提供全面.深入和实用的指导.通过本文的理论解释和实际操作指南,读者能够掌握GAN的核心概念,理解其工作原理,学会设计和训练自己的GAN模型,并能够对结果进行有效 ...

  2. vue3探索——组件通信之事件总线

    Vue2.x使用EventBus进行组件通信,而Vue3.x推荐使用mitt.js. 比起Vue实例上的EventBus,mitt.js好在哪里呢?首先它足够小,仅有200bytes,其次支持全部事件 ...

  3. 《CTFshow-Web入门》04. Web 31~40

    @ 目录 web31 题解 原理 web32 题解 原理 web33 题解 web34 题解 web35 题解 web36 题解 web37 题解 原理 web38 题解 原理 web39 题解 we ...

  4. git status详解

    git status详解 在使用Git进行版本控制时,git status是一个非常有用的命令,用于查看当前代码仓库的状态.它可以告诉你哪些文件已更改.添加或删除,以及是否有未提交的更改等.本篇博客文 ...

  5. Linux安装达梦数据库DM8

    1.简介描述 DM8是达梦公司在总结DM系列产品研发与应用经验的基础上,坚持开放创新.简洁实用的理念,推出的新一代自研数据库.DM8吸收借鉴当前先进新技术思想与主流数据库产品的优点,融合了分布式.弹性 ...

  6. 二叉树(binary tree)

    二叉树(binary tree) 二叉树(Binary Tree)是一种常见的树状数据结构,它由一组节点组成,每个节点最多有两个子节点,分别称为左子节点和右子节点.二叉树具有以下特点: 每个节点最多有 ...

  7. 15.3K Star,超好用的开源协作式数字白板:tldraw

    大家好,我是TJ 今天给大家推荐一个开源协作式数字白板:tldraw. tldraw的编辑器.用户界面和其他底层库都是开源的,你可以在它的开源仓库中找到它们.它们也在NPM上分发,提供开发者使用.您可 ...

  8. js原生 toggle函数编写

    工作中遇到了需要动态切换slide下拉框展示与隐藏,同时需要切换元素上附加的样式,以下脚本为实现此功能的实践. //元素点击时切换隐藏与展示逻辑 var slidsDownShow = documen ...

  9. Solution Set -「CF 1490」

    「CF 1490A」Dense Array Link. 显然不满足的 adjacent elements 之间一直加 \(\min\times2,\min\times4,\cdots,\min\tim ...

  10. C中code关键字

    单片机C语言code是什么作用? code的作用是告诉单片机,我定义的数据要存储在ROM(程序存储区)里面,写入后就不能再更改,其实是相当与汇编里面的寻址MOVC(好像是),因为C语言中没办法详细描述 ...