[SCOI2009] 迷路
题目类型:拆点, 矩阵快速幂
转化为矩阵快速幂,好题!
传送门:>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总共有多少种不同 ...
随机推荐
- Shell基础命令(二)
查看Linux的发行版 cat /etc/redhat-release cat /etc/os-release 查看系统用户的id信息 id 用户名 id root id 创建系统用户的命令 user ...
- 等价路由在路由器和CE交换机上默认的行为是不同的,路由器总是走第一个下一跳,CE交换机是逐包。
结论: 1.在eNSP中实验,路由器和CE交换机对于等价路由的默认转发行为是不同的, 路由器:默认是基于流的转发形态,更准确的来讲,ping两个不同的下一跳,都是走等价路由的第一个路由,不走第二条路由 ...
- clCreateBuffer和clCreateBuufer + clEnqueueWriteBuffer
有两种方式实现从主机到CL设备的数据传递, 第一种: cl_mem input = clCreateBuffer(context,CL_MEM_READ_ONLY,sizeof(float) * DA ...
- Linux 中NFS服务器的搭建
serve端IP:192.168.2.128 客户端IP:192.168.2.131 server端配置: 1.安装nfs,rpcbind,可以参考Linux 中yum的配置来安装: yum inst ...
- 【转载】【时序约束学习笔记1】Vivado入门与提高--第12讲 时序分析中的基本概念和术语
时序分析中的基本概念和术语 Basic concept and Terminology of Timing Analysis 原文标题及网址: [时序约束学习笔记1]Vivado入门与提高--第12讲 ...
- Filebeat使用内置的mysql模块收集日志存储到ES集群并使用kibana存储
Filebeat内置了不少的模块,可以直接使用他们对日志进行收集,支持的模块如下: [root@ELK-chaofeng07 logstash]# filebeat modules list Enab ...
- docker compose 服务启动顺序控制
概要 docker-compose 可以方便组合多个 docker 容器服务, 但是, 当容器服务之间存在依赖关系时, docker-compose 并不能保证服务的启动顺序. docker-comp ...
- 用微软官方的 HTML Help Workshop制作的CHM文件不显示图片解决办法
制作CHM文档,方便小巧还易于查看,用处自不必多说了,最近想把这个季度所学习的内容全部制作成CHM格式文档,给自己后续用来温故而知新,同时也可以做为后起之秀避坑法宝.但是在生成CHM文档之后发现有些地 ...
- RabbitMQ安装,Windows下
一.下载安装ERLANG语言 otp_win64_20.3.exe 一直下一步.然后设置环境变量 ERLANG_HOME C:\Program Files\erl9.3 二.安装RabbitMQ ...
- LVS负载均衡集群
回顾-Nginx反向代理型负载 负载均衡(load balance)集群,提供了一种廉价.有效.透明的方法,来扩展网络设备和服务器的负载.带宽.增加吞吐量.加强网络数据处理能力.提高网络的灵活性和可用 ...