矩阵乘法
每12个单位时间是个循环
前K/12个单位时间用快速幂,后K%12个单位时间用裸矩阵乘法
#include <cstdio>
#include <cstring>
#define MAXN 53
#define MOD 10000
int n, m, s, t, nf;
long T;
int a[12][MAXN][MAXN];
int b[MAXN][MAXN], tmp[MAXN][MAXN];
void multiply(int a[MAXN][MAXN], int b[MAXN][MAXN], int f[MAXN][MAXN])
{
memset(f, 0, sizeof(int) * MAXN * MAXN);
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
for (int k = 0; k < n; ++k)
f[i][j] = (f[i][j] + a[i][k] * b[k][j] % MOD) % MOD;
}
void power(int a[MAXN][MAXN], int b, int f[MAXN][MAXN])
{
if (b == 0)
{
memset(f, 0, sizeof(int) * MAXN * MAXN);
for (int i = 0; i < n; ++i)
f[i][i] = 1;
return;
}
if (b == 1)
{
memcpy(f, a, sizeof(int) * MAXN * MAXN);
return;
}
int t[MAXN][MAXN];
power(a, b / 2, f);
multiply(f, f, t);
if (b % 2 == 0)
memcpy(f, t, sizeof(int) * MAXN * MAXN);
else
multiply(t, a, f);
}
int main()
{
scanf("%d%d%d%d%ld", &n, &m, &s, &t, &T);
memset(a, 0, sizeof(a));
while (m--)
{
int u, v;
scanf("%d%d", &u, &v);
for (int i = 0; i < 12; ++i)
a[i][u][v] = a[i][v][u] = 1;
}
scanf("%d", &nf);
while (nf--)
{
int l, x[4];
scanf("%d", &l);
for (int i = 0; i < l; ++i)
scanf("%d", &x[i]);
for (int i = 0; i < 12; ++i)
for (int j = 0; j < n; ++j)
{
a[i][j][x[(i + 1) % l]] = 0;
a[i][x[i % l]][j] = 0;
}
}
memcpy(b, a[0], sizeof(b));
for (int i = 1; i < 12; ++i)
{
multiply(b, a[i], tmp);
memcpy(b, tmp, sizeof(b));
}
power(b, T / 12, tmp);
memcpy(b, tmp, sizeof(b));
for (int i = 0; i < T % 12; ++i)
{
multiply(b, a[i], tmp);
memcpy(b, tmp, sizeof(b));
}
printf("%d\n", b[s][t]);
return 0;
}