一个DP
用矩阵快速幂加速
然后这个DP状态比较巧妙 以边作状态
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int P=45989;
const int M=125;
struct Matrix{
int a[M][M];
int n;
Matrix(){
}
Matrix(int _n,int i=0){
n=_n; cl(a);
if (i) for (int j=1;j<=n;j++) a[j][j]=1;
}
friend Matrix operator * (const Matrix &A,const Matrix &B){
int n=A.n; Matrix ret(n);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
for (int k=1;k<=n;k++)
(ret.a[i][j]+=A.a[i][k]*B.a[k][j]%P)%=P;
return ret;
}
}A;
struct edge{
int u,v;
edge(int u=0,int v=0):u(u),v(v) { }
}edges[M];
int tot=1;
int n,m,round,S,T;
inline Matrix Pow(Matrix a,int b){
Matrix ret(a.n,1);
for (;b;b>>=1,a=a*a)
if (b&1)
ret=ret*a;
return ret;
}
int ans[M],Ans;
int main()
{
int iu,iv;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(m); read(round); read(S); read(T); S++; T++;
for (int i=1;i<=m;i++)
{
read(iu); read(iv); iu++; iv++;
edges[++tot]=edge(iu,iv); edges[++tot]=edge(iv,iu);
}
A=Matrix(tot);
for (int i=2;i<=tot;i++)
{
for (int j=2;j<=tot;j++)
{
if ((i^1)==j) continue;
if (edges[i].u==edges[j].v)
A.a[i][j]=1;
}
if (edges[i].u==S)
A.a[i][1]=1;
}
A=Pow(A,round);
for (int i=1;i<=tot;i++)
{
ans[i]=A.a[i][1];
if (edges[i].v==T)
(Ans+=ans[i])%=P;
}
printf("%d\n",Ans);
return 0;
}