Description
因为SJY干的奇怪事情过多,SJY收到了休假的通知,于是他准备在都市间来回旅游。SJY有一辆车子,一开始行驶性能为0,每过1时间行驶性能就会提升1点。每个城市的道路都有性能要求。SJY一共有t时间休息,一开始他位于1号城市(保证1号城市道路要求为0),他希望在n号城市结束旅程。每次穿过一条城市间的路会花费1时间,当然他也可以停留在一个城市不动而花费1时间。当且仅当车子的行驶性能大于等于一个城市,我们才能到达那里。SJY希望知道,旅游的方案模10086后的答案。(只要在某一时刻通过的道路存在一条不相同,就算不同的方案)
Input
第一行三个数n,m,t,表示有n个城市m条道路t时间。
第二行n个数,hi表示第i个城市的道路性能要求。
第三到m+2行,每行两个数u,v,表示城市u与城市v之间有一条单向道路连接(可能有重边)。
Output
包括一个数字,表示旅游的方案模10086。
Sample Input
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
Sample Output
245
Data Constraint
对于20%的数据,n<=10,t<=80;
对于50%的数据,n<=30,t<=80;
对于100%的数据,n<=70,m<=1000,t<=100000000,hi<=70。
很容易想到这是个Dp
我们设f[i][j]表示第i时刻,到达第j点的方案总数。
那么随手推一推我们可以得到
f[i][j]=f[i−1][k]∗a[k][j]
其中a[k][j]表示k到j的路径数。
但是这样做显然不能拿到满分
满分做法的话也很简单,做一下矩阵乘法就好了
考虑到h<=70,那么我们可以分段打程序
当t<=70时,暴力dp即可
否则则做矩乘。
CODE
#include
#include
#include
#include
#include
#define fo(i,a,b) for (int i=a;i<=b;i++)
#define fd(i,a,b) for (int i=a;i>=b;i--)
#define N 75
#define INF 1 << 30
#define mo 10086
using namespace std;
typedef int arr[N][N];
arr f,a,g;
int h[1005];
int n,m,t;
int read(int &n)
{
char ch = ' ';
int q = 0, w = 1;
for (;(ch != '-') && ((ch < '0') || (ch> '9'));ch = getchar());
if (ch == '-') w = -1,ch = getchar();
for (; ch >= '0' && ch <= '9';ch = getchar()) q = q * 10 + ch - 48;
n = q * w;
return n;
}
namespace ib {char b[100];}
inline void pint(int x)
{
if (x == 0)
{
putchar(48);
return;
}
if (x < 0)
{
putchar('-');
x = -x;
}
char *s = ib :: b;
while (x) *(++ s) = x % 10,x /= 10;
while (s != ib :: b) putchar((* (s --)) + 48);
}
void Mult(arr &x,arr &y,arr &ans)
{
arr t;
memset(t,0,sizeof(t));
fo(k,1,n)
fo(i,1,n)
if (x[i][k])
fo(j,1,n)
t[i][j] = (t[i][j] + x[i][k] * y[k][j]) % mo;
memcpy(ans,t,sizeof(ans));
}
void Pow(int n,arr &ans)
{
for (;n;n >>= 1,Mult(a,a,a))
if (n & 1) Mult(ans,a,ans);
}
int main()
{
freopen("xor4.in","r",stdin);
read(n),read(m),read(t);
fo(i,1,n) read(h[i]);
fo(i,1,m)
{
int x,y;
read(x),read(y);
a[x][y] ++;
}
fo(i,1,n) a[i][i] ++;
f[0][1] = 1;
fo(i,1,70)
fo(j,1,n)
fo(k,1,n)
if (i >= h[k] && a[j][k]) f[i][k] = (f[i][k] + f[i - 1][j] * a[j][k]) % mo;
if (t <= 70) pint(f[t][n]);
else
{
fo(i,1,n) g[i][i] = 1;
t -= 70;
Pow(t,g);
fo(i,1,n)
fo(k,1,n) f[71][k] = (f[71][k] + f[70][i] * g[i][k] + mo) % mo;
pint(f[71][n]);
}
return 0;
}