[BZOJ 1297][SCOI2009]迷路
1297: [SCOI2009]迷路
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 1418 Solved: 1017
[Submit][Status][Discuss]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
包含一个整数,可能的路径数,这个数可能很大,只需输出这个数除以2009的余数。
Sample Input
【输入样例一】
2 2
11
00【输入样例二】
5 30
12045
07105
47805
12024
12345Sample Output
【输出样例一】
1【样例解释一】
0->0->1【输出样例二】
852HINT
30%的数据,满足 2 <= N <= 5 ; 1 <= T <= 30 。 100%的数据,满足 2 <= N <= 10 ; 1 <= T <= 1000000000 。
一周之前做的了...想了想还是写写题解吧...
题解
首先我们都知道的一个结论是对于一个简单图 $G$ 的邻接矩阵 $M$ , $M^k_{i,j}$ 就是从点 $i$ 走 $k$ 条边到点 $j$ 的方案数.
然而这个结论只适用于两点间的边数, 而我们注意到本题中两点间的边是带权的, 我们就不能直接使用这个结论了
接着我们可以想到的其中一个解法是把一条边权为 $k$ 的边通过在其中插入虚拟结点的方式拆成 $k$ 条边, 但是极端情况下可能有 $100$ 条带权边要拆, 每条带权边可能会拆成 $10$ 条无权边, 其中会产生大量虚拟结点, 极端情况下总结点数会大于 $1000$ , 矩阵相应的也会变成这个数量级, 然后一次 $O(n^3)$ 的矩阵乘法都跑不完...╮(╯﹏╰)╭
继续思考优化方式, 现在的瓶颈在于虚拟结点过多, 我们可以思考如何缩减虚拟结点的数量. 我们可以尝试事先将一些虚拟结点和原结点连成链, 然后对于带权边都指向这条链上的对应位置, 将带权边前方的链合并起来(一股Trie的味道?)来最小化结点数量, 这样就可以把结点数量控制在 $100$ 的量级
然后就很棒棒了, 构造完矩阵无脑跑快速幂就好了(o゚▽゚)o
反正别像我一样打出了正解输出的时候把倍增矩阵当成答案矩阵输出就行了( ̄. ̄)
参考代码
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm> const int MAXN=;
const int MOD=; int n,t;
char buf[MAXN];
int m[MAXN][MAXN];
int x[MAXN][MAXN];
int mt[MAXN][MAXN]; int Encode(int);
void Initialize();
int Encode(int,int); int main(){
Initialize();
// t--;
while(t>){
if((t&)!=){
memset(mt,,sizeof(mt));
for(int i=;i<n*;i++)
for(int j=;j<n*;j++)
for(int k=;k<n*;k++)
(mt[i][j]+=x[i][k]*m[k][j])%=MOD;
memcpy(x,mt,sizeof(mt));
}
memset(mt,,sizeof(mt));
for(int i=;i<n*;i++)
for(int j=;j<n*;j++)
for(int k=;k<n*;k++)
(mt[i][j]+=m[i][k]*m[k][j])%=MOD;
memcpy(m,mt,sizeof(mt));
t>>=;
}
printf("%d\n",x[][Encode(n-)]);
return ;
} void Initialize(){
scanf("%d%d",&n,&t);
for(int i=;i<n;i++){
for(int j=;j<=;j++){
m[Encode(i,j)][Encode(i,j-)]=;
}
}
for(int i=;i<n;i++){
scanf("%s",buf);
for(int j=;j<n;j++){
if(buf[j]!=''){
m[Encode(i)][Encode(j,buf[j]-'')]=;
}
}
}
for(int i=;i<n*;i++)
x[i][i]=;
} inline int Encode(int k,int len){
return k*+len-;
} inline int Encode(int k){
return k*;
}
Backup

[BZOJ 1297][SCOI2009]迷路的更多相关文章
- BZOJ 1297: [SCOI2009]迷路( dp + 矩阵快速幂 )
递推式很明显...但是要做矩阵乘法就得拆点..我一开始很脑残地对于每一条权值v>1的边都新建v-1个节点去转移...然后就TLE了...把每个点拆成9个就可以了...时间复杂度O((9N)^3* ...
- BZOJ 1297: [SCOI2009]迷路 [矩阵快速幂]
Description windy在有向图中迷路了. 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1. 现在给出该有向图,你能告诉windy总共有多少种不同 ...
- 1297: [SCOI2009]迷路
1297: [SCOI2009]迷路 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 652 Solved: 442[Submit][Status] ...
- 【BZOJ】1297: [SCOI2009]迷路
[题意]给定n个点的有向带边权图,求0到n-1长度恰好为T的路径数.n<=10,T<=10^9,边权1<=wi<=9. [算法]矩阵快速幂 [题解]这道题的边权全部为1时,有简 ...
- 1297. [SCOI2009]迷路【矩阵乘法】
Description windy在有向图中迷路了. 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1. 现在给出该有向图,你能告诉windy总共有多少种不同 ...
- 【矩阵快速幂】bzoj1297 [SCOI2009]迷路
1297: [SCOI2009]迷路 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1407 Solved: 1007[Submit][Status ...
- [Bzoj1297][Scoi2009 ]迷路 (矩阵乘法 + 拆点)
1297: [SCOI2009]迷路 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1385 Solved: 993[Submit][Status] ...
- 【BZOJ1297】[SCOI2009]迷路(矩阵快速幂)
[BZOJ1297][SCOI2009]迷路(矩阵快速幂) 题面 BZOJ 洛谷 题解 因为边权最大为\(9\),所以记录往前记录\(9\)个单位时间前的.到达每个点的方案数就好了,那么矩阵大小就是\ ...
- B20J_1297_[SCOI2009]迷路_矩阵乘法
B20J_1297_[SCOI2009]迷路_矩阵乘法 题意:有向图 N 个节点,从节点 0 出发,必须恰好在 T 时刻到达节点 N-1.总共有多少种不同的路径? 2 <= N <= 10 ...
随机推荐
- Linux显示版本信息并退出
Linux显示版本信息并退出 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ cat --version cat (GNU coreutils) 8.21 Co ...
- hibernate学习(三) hibernate中的对象状态
hibernate对象的状态分为三种: 游离状态,持久化状态,瞬时状态 下面一行代码区分: Configuration cfg=new Configuration().configure(); ...
- Django学习-13-simple_tag使用
一些HTML方法 {{item.event_start | date:"Y-m-d H:i:s"}} {{bi ...
- Spring有什么缺点?
Spring有什么缺点如下: 1.jsp中要写很多代码: 2.控制器过于灵活,缺少一个公用控制器: 3.不支持分布式部署.
- 【BZOJ3140】消毒(二分图匹配)
[BZOJ3140]消毒(二分图匹配) 题面 Description 最近在生物实验室工作的小T遇到了大麻烦. 由于实验室最近升级的缘故,他的分格实验皿是一个长方体,其尺寸为abc,a.b.c 均为正 ...
- [UOJ207]共价大爷游长沙
UOJ sol 这题真是太神啦! 对于S集合中的每个点对,给他们随机附上一个相同权值. 两个点在边(x,y)的两侧当且仅当一个点在x的子树中,另一个点不在x的子树中(假设x是y的儿子) 维护一下子树点 ...
- Redis持久化方案
Redis可以实现数据的持久化存储,即将数据保存到磁盘上. Redis的持久化存储提供两种方式:RDB与AOF.RDB是默认配置.AOF需要手动开启. 默认redis是会以快照的形式将数据持久化到磁盘 ...
- 在eclipse中API的封装和调用
自己写的API的封装和调用:1.写好api的方法的实现类.2.抽取一个javadoc文档.file->Export->java->javadoc->finish->Yes ...
- jQuery中有关mouse的事件--mousedown/up/enter/leave/over/out----2017-05-10
mousedown:鼠标按下才发生 mouseup:鼠标按下松开时才发生 mouseenter和mouseleave效果和mouseover mouseout效果差不多:但存在区别,区别见代码解析: ...
- python解决图的最短路径问题
在hihoCoder上遇到一个算法题目,描述如下: 对图结构有了解的不难发现,这是经典的求图的最短路径问题.以下是python代码: def findMin(row): minL = max(row) ...