bzoj1297 / P4159 [SCOI2009]迷路

P4159 [SCOI2009]迷路

如果边权只有 0/1 那么不就是一个灰常简单的矩阵快速幂吗!

然鹅边权 $<=9$

所以我们把每个点拆成9个点!

解决~

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define re register
 5 using namespace std;
 6 const int mod=2009;
 7 int m,n,t;long long q;
 8 struct matrix{
 9     int a[92][92];
10     matrix(){memset(a,0,sizeof(a));}
11     matrix operator * (const matrix &tmp) const{
12         matrix c;
13         for(int i=1;i<=n;++i)
14             for(int j=1;j<=n;++j)
15                 for(int k=1;k<=n;++k)
16                     c.a[i][j]=(c.a[i][j]+a[i][k]*tmp.a[k][j])%mod;
17         return c;
18     }
19     matrix Pow(matrix x,int y){
20         matrix res;
21         for(int i=1;i<=n;++i) res.a[i][i]=1;
22         for(;y;y>>=1,x=x*x)
23             if(y&1) res=res*x;
24         return res;
25     }
26 }st;
27 int idx(int x,int y){return x+m*y;}//新点编号
28 int main(){
29     scanf("%d%d",&m,&t);n=m*9;
30     for(int i=1;i<=m;++i){
31         for(int j=1;j<=8;++j)
32             st.a[idx(i,j)][idx(i,j-1)]=1;//规定idx(i,0)作为原图的点向其他点连边,其他点与该点的边权就转化为连到idx(i,dist-1)上
33         scanf("%lld",&q);
34         for(int j=m;j>=1;--j,q/=10)
35             if(q%10) st.a[i][idx(j,q%10-1)]=1;
36     }st=st.Pow(st,t);
37     printf("%d",st.a[1][m]);
38     return 0;
39 }

原文地址:https://www.cnblogs.com/kafuuchino/p/9902354.html

时间: 2024-10-29 10:47:44

bzoj1297 / P4159 [SCOI2009]迷路的相关文章

P4159 [SCOI2009]迷路

传送门 先考虑只有 01 边权的情况 显然可以DP+矩阵加速 但是现在边权不止 1 然鹅最大也只有 9 所以从这里入手,把点拆成 9 个,然后点之间的边权也就可以变成 1 了 同样的转移和矩阵加速 注意点之间的连接关系 #include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<cstring> using namespace std; inli

矩阵乘法专题1——bzoj 1297 [SCOI2009] 迷路题解

题目链接 题意:给两个长度分别为n和m的序列,现在有两种操作:1.分别选择两个序列的一个非空前缀,切两个前缀的最后一位相同,删除之,得到1分(只累计),消耗e:2.直接删除两个序列,消耗值定于两个序列之前删除的元素个数之和,并且使得得到的分有效(之前没有有效分) 分析: 首先,问题其实就是转化成,进行若干次操作1,然后进行操作2 还要找到一个判别标准,来评判较优的状态(贪心) 每次的消耗值比较大,其实可以计算出最大的删除次数,这个值不是很大 状态表示: 简单的,一个状态可以表示为串A的位置.串B

1297: [SCOI2009]迷路

1297: [SCOI2009]迷路 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 652  Solved: 442[Submit][Status] Description windy在有向图中迷路了. 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1. 现在给出该有向图,你能告诉windy总共有多少种不同的路径吗? 注意:windy不能在某个节点逗留,且通过某有向边的时间严格为给定的时间. Input

[BZOJ 1297][SCOI2009]迷路

1297: [SCOI2009]迷路 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1418  Solved: 1017[Submit][Status][Discuss] Description windy在有向图中迷路了. 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1. 现在给出该有向图,你能告诉windy总共有多少种不同的路径吗? 注意:windy不能在某个节点逗留,且通过某有向边的时间严格为给定

BZOJ1297 [SCOI2009]迷路

Description windy在有向图中迷路了. 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1. 现在给出该有向图,你能告诉windy总共有多少种不同的路径吗? 注意:windy不能在某个节点逗留,且通过某有向边的时间严格为给定的时间. Input 第一行包含两个整数,N T. 接下来有 N 行,每行一个长度为 N 的字符串. 第i行第j列为'0'表示从节点i到节点j没有边. 为'1'到'9'表示从节点i到节点j需要耗费的时间. Output 包

BZOJ1297 [SCOI2009]迷路 【矩阵优化dp】

题目 windy在有向图中迷路了. 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1. 现在给出该有向图,你能告诉windy总共有多少种不同的路径吗? 注意:windy不能在某个节点逗留,且通过某有向边的时间严格为给定的时间. 输入格式 第一行包含两个整数,N T. 接下来有 N 行,每行一个长度为 N 的字符串. 第i行第j列为'0'表示从节点i到节点j没有边. 为'1'到'9'表示从节点i到节点j需要耗费的时间. 输出格式 包含一个整数,可能的路径数

BZOJ1297 SCOI2009 迷路 矩阵乘法

题意:给定一张有N个点的有向图,求0到N-1长度为T的路径的总条数. 题解:把长度为K的边拆成K条长度为1的边,然后建出邻接矩阵快速幂裸上. #include <cstdio> #include <cstring> #include <cstdlib> #include <climits> #include <iostream> #include <algorithm> using namespace std; #define P(x

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

题目大意:有向图里10个点,点与点之间距离不超过9,问从1刚好走过T距离到达n的方案数. 当时看到这题就想到了某道奶牛题(戳我).这两道题的区别就是奶牛题问的是走T条边,这道题是每条边都有一个边权求走过T边权的方案数...所以可以看成奶牛题相当于这一题里的边权为1的情况. 首先边权为1就把奶牛题的floyd那段改成矩乘就可以了,那么接下来考虑边权不为1的情况,因为边权最多为9,我们就可以把每个点拆成9个点,x[1]~x[9]为x拆完的点,x[i]和x[i+1]连一条边权为1的边,然后x到y有一条

bzoj1297 [SCOI2009]迷路——拆点+矩阵快速幂

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1297 一看感觉是矩阵快速幂之类的,但边权不好处理啊: 普通的矩阵快速幂只能处理边权为1的,所以想办法把边权处理成1: 仔细一看还有一个条件是边权小于10: 所以拆点!把一个点拆成10个点表示到它不同的距离,那么和它相连的那些点就可以跟某个距离的点连边权为1的边: 虽然没有自己想出来,不过1A还是极好的!(因为太简单了) 代码如下: #include<iostream> #include&