[SDOI 2009] HH去散步
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1875
[算法]
用f[i][j]表示现在在走了i步 , 在第j条边的方案数
矩阵加速 , 即可
时间复杂度 : O(N ^ 3logN)
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 125 const int P = 45989; struct edge { int to , nxt; } e[MAXN << 1]; int n , m , t , A , B , tot; int head[MAXN]; struct matrix_t { int mat[MAXN][MAXN]; } a , b; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } inline void addedge(int u,int v) { tot++; e[tot] = (edge){v , head[u]}; head[u] = tot; } inline void multipy(matrix_t &a , matrix_t b) { static matrix_t ret; for (int i = 1; i <= tot; i++) { for (int j = 1; j <= tot; j++) { ret.mat[i][j] = 0; } } for (int i = 1; i <= tot; i++) { for (int j = 1; j <= tot; j++) { for (int k = 1; k <= tot; k++) { ret.mat[i][j] = (ret.mat[i][j] + 1LL * a.mat[i][k] * b.mat[k][j]) % P; } } } a = ret; } inline void exp_mod(matrix_t &a , int t) { static matrix_t tmp; for (int i = 1; i <= tot; i++) { for (int j = 1; j <= tot; j++) { tmp.mat[i][j] = (i == j); } } while (t > 0) { if (t & 1) multipy(tmp , a); multipy(a , a); t >>= 1; } a = tmp; } int main() { read(n); read(m); read(t); read(A); read(B); ++A; ++B; tot = 1; for (int i = 1; i <= m; i++) { int u , v; read(u); read(v); ++u; ++v; addedge(u , v); addedge(v , u); } for (int i = 2; i <= tot; i++) { for (int j = 2; j <= tot; j++) { if (i != (j ^ 1) && e[j ^ 1].to == e[i].to) ++b.mat[i][j]; } } for (int i = head[A]; i; i = e[i].nxt) ++a.mat[1][i]; exp_mod(b , t - 1); multipy(a , b); int ans = 0; for (int i = head[B]; i; i = e[i].nxt) ans = (ans + 1LL * a.mat[1][i ^ 1]) % P; printf("%d\n" , ans); return 0; }