[ZJOI2005]沼泽鳄鱼
Description
Solution
K那么大肯定是矩阵快速幂了。转移矩阵就是邻接矩阵,食人鱼只有2,3,4,显然是有以12为周期的循环的,然后就一起矩乘就好了。
Code
const int N = 55;
const int mod = 10000;
int n, m, St, Ed, K, tmp[15];
struct Matrix {
int s[N][N];
void clear() { memset(s, 0, sizeof s); }
void init() {
clear();
for (int i = 1; i <= n; ++i) s[i][i] = 1;
}
int* operator[](int x) { return s[x]; }
} S, T[15];
Matrix operator*(Matrix& x, Matrix& y) {
Matrix ret;
ret.clear();
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
for (int k = 1; k <= n; ++k) {
ret[i][j] = (ret[i][j] + x[i][k] * y[k][j]) % mod;
}
}
}
return ret;
}
Matrix pow_mod(Matrix x, int p) {
Matrix ret;
ret.init();
for (; p; p >>= 1, x = x * x) {
if (p & 1) ret = ret * x;
}
return ret;
}
void main() {
n = read(), m = read(), St = read() + 1, Ed = read() + 1, K = read();
S.clear();
for (int i = 1, x, y; i <= m; ++i) {
x = read() + 1, y = read() + 1;
S[x][y] = S[y][x] = 1;
}
for (int i = 1; i <= 12; ++i) T[i] = S;
int nf = read();
while (nf--) {
int t = read();
for (int i = 0; i < t; ++i) tmp[i] = read() + 1;
for (int j = 1; j <= n; ++j)
for (int i = 1; i <= 12; ++i) T[i][j][tmp[i % t]] = 0;
}
S.init();
for (int i = 1; i <= 12; ++i) S = S * T[i];
S = pow_mod(S, K / 12);
for (int i = 1; i <= K % 12; ++i) S = S * T[i];
printf("%d\n", S[St][Ed]);
}