题目描述
因为SJY干的奇怪事情过多,SJY收到了休假的通知,于是他准备在都市间来回旅游。SJY有一辆车子,一开始行驶性能为0,每过1时间行驶性能就会提升1点。每个城市的道路都有性能要求。SJY一共有t时间休息,一开始他位于1号城市(保证1号城市道路要求为0),他希望在n号城市结束旅程。每次穿过一条城市间的路会花费1时间,当然他也可以停留在一个城市不动而花费1时间。当且仅当车子的行驶性能大于等于一个城市,我们才能到达那里。SJY希望知道,旅游的方案模10086后的答案。(只要在某一时刻通过的道路存在一条不相同,就算不同的方案)
输入
第一行三个数n,m,t,表示有n个城市m条道路t时间。
第二行n个数,hi表示第i个城市的道路性能要求。
第三到m+2行,每行两个数u,v,表示城市u与城市v之间有一条单向道路连接(可能有重边)。
输出
包括一个数字,表示旅游的方案模10086。
样例输入
5 17 7
0 2 4 5 3
1 2
2 1
1 3
3 1
1 4
4 1
4 5
5 4
5 3
4 1
2 1
5 3
2 1
2 1
1 2
2 1
1 3
样例输出
245
提示
【数据规模和约定】
对于20%的数据,n<=10,t<=80;
对于50%的数据,n<=30,t<=80;
对于100%的数据,n<=70,m<=1000,t<=100000000,hi<=70。
对于50%的数据,很容易想到dp转移方程,记dp[i,j]表示i时刻到j点的方案总数,dp[i,j]=dp[i-1,k]*a[k,j]; a[k,j]为k到j的路经数。
对于100%的数据,我们发现hi<=70,也就是说70s以后我们就可以随便走了,于是我们想到了矩阵乘法,70s以后直接用矩阵算,70s之前用dp算。
type al=array[0..80,0..80] of longint;
var
n,m,t,i,x,y,j,k:longint;
a,dp,f,ans:al;
h:array[0..1000] of longint;
function chen(x,y:al):al;
var
i,j,k:longint;
begin
for i:=1 to n do
for j:=1 to n do
begin
chen[i,j]:=0;
for k:=1 to n do
chen[i,j]:=(chen[i,j]+x[i,k]*y[k,j]) mod 10086;
end;
end;
function gpow(k:longint):al;
var
t:al;
begin
if k=1 then exit(a);
t:=gpow(k div 2);
t:=chen(t,t);
if k mod 2=1 then t:=chen(t,a);
exit(t);
end;
begin
readln(n,m,t);
for i:=1 to n do
read(h[i]);
readln;
for i:=1 to m do
begin
readln(x,y);
a[x,y]:=a[x,y]+1;
end;
for i:=1 to n do
a[i,i]:=a[i,i]+1;
dp[0,1]:=1;
for i:=1 to 70 do
for j:=1 to n do
for k:=1 to n do
if (i>=h[k])and(a[j,k]>0) then dp[i,k]:=(dp[i,k]+dp[i-1,j]*a[j,k]) mod 10086;
if t<=70 then write(dp[t,n])
else
begin
ans:=gpow(t-70);
for i:=1 to n do
for k:=1 to n do
dp[71,k]:=(dp[71,k]+dp[70,i]*ans[i,k]) mod 10086;
write(dp[71,n]);
end;
end.