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
12345

Sample Output

【输出样例一】
1

【样例解释一】
0->0->1

【输出样例二】
852

HINT

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

反正别像我一样打出了正解输出的时候把倍增矩阵当成答案矩阵输出就行了( ̄. ̄)

参考代码

GitHub

 #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]迷路的更多相关文章

  1. BZOJ 1297: [SCOI2009]迷路( dp + 矩阵快速幂 )

    递推式很明显...但是要做矩阵乘法就得拆点..我一开始很脑残地对于每一条权值v>1的边都新建v-1个节点去转移...然后就TLE了...把每个点拆成9个就可以了...时间复杂度O((9N)^3* ...

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

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

  3. 1297: [SCOI2009]迷路

    1297: [SCOI2009]迷路 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 652  Solved: 442[Submit][Status] ...

  4. 【BZOJ】1297: [SCOI2009]迷路

    [题意]给定n个点的有向带边权图,求0到n-1长度恰好为T的路径数.n<=10,T<=10^9,边权1<=wi<=9. [算法]矩阵快速幂 [题解]这道题的边权全部为1时,有简 ...

  5. 1297. [SCOI2009]迷路【矩阵乘法】

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

  6. 【矩阵快速幂】bzoj1297 [SCOI2009]迷路

    1297: [SCOI2009]迷路 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1407  Solved: 1007[Submit][Status ...

  7. [Bzoj1297][Scoi2009 ]迷路 (矩阵乘法 + 拆点)

    1297: [SCOI2009]迷路 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1385  Solved: 993[Submit][Status] ...

  8. 【BZOJ1297】[SCOI2009]迷路(矩阵快速幂)

    [BZOJ1297][SCOI2009]迷路(矩阵快速幂) 题面 BZOJ 洛谷 题解 因为边权最大为\(9\),所以记录往前记录\(9\)个单位时间前的.到达每个点的方案数就好了,那么矩阵大小就是\ ...

  9. B20J_1297_[SCOI2009]迷路_矩阵乘法

    B20J_1297_[SCOI2009]迷路_矩阵乘法 题意:有向图 N 个节点,从节点 0 出发,必须恰好在 T 时刻到达节点 N-1.总共有多少种不同的路径? 2 <= N <= 10 ...

随机推荐

  1. Servlet.service() for Servlet jsp threw exception javax.servlet.ServletException:File &quot;/pageFoo

    1.错误描述 Servlet.service() for Servlet jsp threw exception javax.servlet.ServletException:File "/ ...

  2. (十七)java冒泡排序和compareto

    java中的排序有:冒泡排序.快速排序.选择排序.插入排序和希尔排序,还有基数排序.鸡尾酒排序.桶排序.鸽巢排序.归并排序等.     冒泡排序法:利用双重for循环,重复走访要排序的数列,两两比较大 ...

  3. Linux查看系统中的每个进程

    Linux查看系统中的每个进程 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ ps -A PID TTY TIME CMD 1 ? 00:00:01 init ...

  4. 多线程下不重复读取SQL Server 表的数据

    在进行一些如发送短信.邮件的业务时,我们经常会使用一个表来存储待发送的数据,由后台多个线程不断的从表中读取待发送的数据进行发送,发送完成后再将数据转移到历史表中,这样保证待发送表的数据一般情况下不会太 ...

  5. View的放大->旋转->还原动画

    以UIButton为例,创建一个类,继承于UIButton /*页面的创建用storyboard*/ .h文件  @interface PTSRecommendButton : UIButton - ...

  6. 【BZOJ3238】差异(后缀自动机)

    [BZOJ3238]差异(后缀自动机) 题面 BZOJ 题解 前面的东西直接暴力算就行了 其实没必要算的正正好 为了方便的后面的计算 我们不考虑\(i,j\)的顺序问题 也就是先求出\(\sum_{i ...

  7. [ZJOI2006]书架(树状数组水过)

    这道题显然平衡树,splay,treap什么的随便切 然而我不想打,决定水过这道题 把空间开3倍,树状数组维护它前面的树的个数,开个id数组记录位置 找一个数排名直接二分加求前缀和,log^2的搞一搞 ...

  8. 微信小程序之换肤的功能

    pc或者移动端实现换肤功能还是比较简单的,大致就是需要换肤的css,还有正常的css:把当前皮肤类型存入本地:然后通过js读取并判断当前应该加载哪套css. 由于微信小程序没有操作wxss的api,所 ...

  9. css中的注意项,可能会帮助到大家哦!

    CSS样式层叠表 1.link与@import的区别(5点) (1).link为XHTML的标签,可以引进CSS样式表,除了引进CSS文件还可以引进其他的文件如.js或.rss文件;@import为C ...

  10. NancyFX 第五章 Nancy 路由

    在Nancy中,最为神奇的莫过于路由了,定义路由模块是构成Nancy应用的骨架.在Nancy中定义路由,和在 ASP.NET MVC那些类似的框架中有着非常大的区别. 以 ASP.NET MVC 为例 ...