题目大意
给一个无向图,起点和终点(stand,end)。从起点到终点,要走过t条边(t给定)。每条边的权值都是单位1。一些点中会有食人鱼,食人鱼会在k(2<=k<=4)个点之间循环,当循环到改点时则不能待在改点上。求从起点恰好走完t个单位时间后到达终点的路径条数。
分析
用矩阵乘法解此题。在没有食人鱼时,直接建立邻接矩阵A,然后求从起点到终点的方案数。A^t,输出A[s,e]即可。
但现在有了食人鱼。观察后发现,一条食人鱼的活动周期只可能是2,3,4,所以所有的食人鱼的一个大的活动周期是12(2,3,4的最小公倍数)。即,我们可以推出12个时刻的邻接矩阵(f[1],f[2],f[3]…f[12])(表示此时刻可以走的点和路)。然后,把十二个矩阵相乘得到矩阵A,再求A^(t div 12)。
因为t/12会有余数,设余数为x,就代表还有x个时刻没算,所以A要乘f[1],f[2]...f[x]。最后输出A[s,e] mod 10000,即可。
type
arr=array[0..100,0..100] of longint;
var
a:array[1..100] of arr;
d:array[1..100,0..10] of longint;
n,m,f:longint;
x,y:longint;
ans:int64;
i,j,k,l:longint;
function cheng(x,x1:arr):arr;
var
i,j,k:longint;
begin
fillchar(cheng,sizeof(cheng),0);
for i:=1 to n do
for j:=1 to n do
for k:=1 to n do
cheng[i,j]:=(cheng[i,j]+x[i,k]*x1[k,j]) mod 10000;
end;
procedure seach(n:longint);
var
i,j,k:longint;
begin
if n=0 then exit;
seach(n div 2);
a[15]:=cheng(a[15],a[15]);
if n mod 2=1 then a[15]:=cheng(a[15],a[13]);
end;
begin
readln(n,m,x,y,ans);
for i:=1 to m do
begin
readln(j,k);
j:=j+1; k:=k+1;
a[13,j,k]:=1;
a[13,k,j]:=1;
end;
readln(f);
for i:=1 to f do
begin
read(j);
for k:=1 to j do
begin
read(d[i,k]);
d[i,k]:=d[i,k]+1;
end;
d[i,0]:=j;
readln;
end;
for i:=1 to 12 do
a[i]:=a[13];
for i:=1 to f do
begin
for j:=1 to 12 do
begin
l:=j mod d[i,0];
if l=0 then l:=d[i,0];
for k:=1 to n do
a[j][d[i,l]][k]:=0;
end;
end;
for i:=1 to n do
a[15][i][i]:=1;
for i:=1 to 12 do
a[15]:=cheng(a[15],a[i]);
a[13]:=a[15];
a[15]:=a[16];
for i:=1 to n do
a[15][i][i]:=1;
seach(ans div 12);
for i:=1 to ans mod 12 do
a[15]:=cheng(a[15],a[i]);
write(a[15][x+1][y+1] mod 10000);
end.