传送门
首先我们发现t特别大,n特别小。
这启示我们用矩阵乘法做。
设f[i][j]表示从i到j的方案数。
显然这是支持矩阵乘法的。
时间复杂度O(N^3*logT)
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#define ll long long
using namespace std;
int n,m,T,s,t,x,y,ans,tot=2,head[130];
struct matrix{
int a[130][130];
void clear(){memset(a,0,sizeof(a));}
}ppp,qqq,rrr,sss;
matrix mult(matrix x,matrix y){
matrix z;
z.clear();
for (int i=0;i<tot;i++)
for (int j=0;j<tot;j++)
for (int k=0;k<tot;k++)
z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j])%45989;
return z;
}
matrix pow(matrix c,int x){
matrix b;
b.clear();
for (int i=0;i<tot;i++) b.a[i][i]=1;
while (x){
if (x&1) b=mult(b,c);
c=mult(c,c);
x/=2;
}
return b;
}
struct edge{int to,next;}e[150];
inline void add(int x,int y){
e[tot].to=y;
e[tot].next=head[x];
head[x]=tot;
tot++;
}
int main(){
memset(head,-1,sizeof(head));
scanf("%d%d%d%d%d",&n,&m,&T,&s,&t);
for (int i=1;i<=m;i++){
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
for (int i=head[s];i!=-1;i=e[i].next) ppp.a[0][i]=1;
for (int i=2;i<tot;i++){
int v=e[i].to;
for (int j=head[v];j!=-1;j=e[j].next)
if (i!=(j^1)) qqq.a[i][j]=1;
}
rrr=pow(qqq,T-1);
sss=mult(ppp,rrr);
ans=0;
for (int i=0;i<tot;i++)
if (e[i].to==t) ans=(ans+sss.a[0][i])%45989;
printf("%d",ans);
}