这个还是想了很久 第一次见这种把边看成点的邻接矩阵
由于是无向图 两条边会一起加 第i条边过后你就不能使用第i ^ 1条边了
提前记录连接起点和终点的边即可
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXM = 120;
const int MAXN = 20;
const int p = 45989;
struct Matrix {
int n, m;
int A[MAXM+10][MAXM+10];
}Map, E, Z, MAP;
typedef pair<int, int> pii;
pii Edge[MAXM+10];
int n, m, K, st, ed, ecnt, N;
int EI[MAXN+10], EO[MAXN+10], In, Out;
void GET_E()
{
E.n = E.m = N;
for(int i = 0; i < N; i++)
E.A[i][i] = 1;
}
Matrix mul(Matrix A, Matrix B) {
Matrix D;
D.n = A.n;
D.m = A.m;
memset(D.A, 0, sizeof(D.A));
for (int i = 0; i < D.n; i++) {
for (int j = 0; j < D.m; j++) {
for (int k = 0; k < A.m; k++) {
D.A[i][j] += A.A[i][k] * B.A[k][j];
D.A[i][j] %= p;
}
}
}
return D;
}
Matrix pow_mod(Matrix &A, int k)
{
Matrix ans = E, t = A;
ans.n = A.n;
ans.m = A.m;
while(k)
{
if(k & 1)
ans = mul(ans, t);
t = mul(t, t);
k >>= 1;
}
return ans;
}
int main()
{
scanf("%d%d%d%d%d", &n, &m, &K, &st, &ed);
for(int i = 0; i < m; i++)
{
int u, v;
scanf("%d%d", &u, &v);
Edge[ecnt++] = make_pair(u, v);
Edge[ecnt++] = make_pair(v, u);
}
N = ecnt;
Matrix ANS;
for(int i = 0; i < N; i++)
{
if(Edge[i].first == st) EI[In++] = i;
if(Edge[i].second == ed) EO[Out++] = i;
for(int j = 0; j < N; j++)
if(i != j && i != (j ^ 1) && Edge[i].second == Edge[j].first)
MAP.A[i][j] = 1;
}
GET_E();
MAP.n = MAP.m = N;
Map.n = 1; Map.m = N;
for(int i = 0; i < In; i++) Map.A[0][EI[i]] = 1;
MAP = pow_mod(MAP, K-1);
ANS = mul(Map, MAP);
int cnt = 0;
for(int i = 0; i < Out; i++)
{
cnt += ANS.A[0][EO[i]];
cnt %= p;
}
printf("%d", cnt);
}