题目要求对于同一条边,不能走过去后立刻走回来,所以很明显我们需要把一条边拆成两条来做。
此时我们的状态也需要改变:num[i][j][t]表示从第i条边到第j条边,经过时间为t的方案数。
因为我们的方案是设第i条边到第j条边,所以初始矩阵赋值时,其实已经过去了一个单位的时间。所以我们只需要,再累乘矩阵T-1次即可。
#include <bits/stdc++.h>
using namespace std;
const int N=130,MOD=45989;
int n,m,t,A,B,cnt,u,v,sum;
struct edge{int x,y;}e[N];
struct number{int num[N][N];}a,ans;
inline number mul(number a,number b)
{
number c;
for (register int i=2; i<=cnt; ++i)
for (register int j=2; j<=cnt; ++j) c.num[i][j]=0;
for (register int i=2; i<=cnt; ++i)
for (register int j=2; j<=cnt; ++j)
for (register int k=2; k<=cnt; ++k)
c.num[i][j]=(c.num[i][j]+a.num[i][k]*b.num[k][j]%MOD)%MOD;
return c;
}
inline void pow(int k)
{
while (k)
{
if (k&1) ans=mul(ans,a);
a=mul(a,a);
k>>=1;
}
}
int main(){
scanf("%d%d%d%d%d",&n,&m,&t,&A,&B);
cnt=1;
for (register int i=1; i<=m; ++i)
{
scanf("%d%d",&u,&v);
e[++cnt].x=u; e[cnt].y=v;
e[++cnt].x=v; e[cnt].y=u;
}
for (register int i=2; i<=cnt; ++i)
for (register int j=2; j<=cnt; ++j) if (i!=(j^1) && e[i].y==e[j].x) a.num[i][j]=1;
for (register int i=2; i<=cnt; ++i) ans.num[i][i]=1;
pow(t-1);
for (register int i=2; i<=cnt; ++i)
for (register int j=2; j<=cnt; ++j)
if (e[i].x==A && e[j].y==B) sum=(sum+ans.num[i][j])%MOD;
printf("%d\n",sum);
return 0;
}