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
第一行包含两个整数,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
2 2
11
00
【输入样例二】
5 30
12045
07105
47805
12024
12345
Sample Output
【输出样例一】
1
【样例解释一】
0->0->1
【输出样例二】
852
1
【样例解释一】
0->0->1
【输出样例二】
852
HINT
30%的数据,满足 2 <= N <= 5 ; 1 <= T <= 30 。
100%的数据,满足 2 <= N <= 10 ; 1 <= T <= 1000000000 。
Source
题解:我这辈子做的第一道真正意义上的矩阵乘法么么哒(phile:这。。。 HansBug:讨厌啦,都说了不要鄙视本宫TT)。。。据说矩阵乘法超级神奇,于是按照XXXXXXX来了一发。。。接下来还得继续学习,么么么哒~~~~
1 const p=2009; 2 type 3 sq=array[0..105,0..105] of longint; 4 var 5 i,j,k,l,m,n:longint; 6 a,b:sq; 7 cx:char; 8 function cc(a,b:sq):sq; 9 var 10 c:sq; 11 begin 12 fillchar(c,sizeof(c),0); 13 for k:=1 to n*9 do 14 for i:=1 to n*9 do 15 for j:=1 to n*9 do 16 c[i,j]:=(c[i,j]+(a[i,k]*b[k,j]) mod p) mod p; 17 cc:=c; 18 end; 19 procedure digit(var a:sq); 20 begin 21 fillchar(a,sizeof(a),0); 22 for i:=1 to n*9 do a[i,i]:=1; 23 end; 24 function ksm(a:sq;x:longint):sq; 25 var 26 c1,c2:sq; 27 begin 28 digit(c1);c2:=a; 29 while x>0 do 30 begin 31 if odd(x) then c1:=cc(c1,c2); 32 c2:=cc(c2,c2); 33 x:=x div 2; 34 end; 35 ksm:=c1; 36 end; 37 begin 38 readln(n,m); 39 for i:=1 to n do 40 for j:=2 to 9 do 41 a[i*9-9+j,i*9-9+j-1]:=1; 42 for i:=1 to n do 43 begin 44 for j:=1 to n do 45 begin 46 read(cx); 47 if cx<>'0' then 48 a[j*9-8,i*9-9+ord(cx)-48]:=1; 49 end; 50 readln; 51 end; 52 b:=ksm(a,m); 53 writeln(b[n*9-8,1]); 54 end.