矩阵乘法。
这题等于是VJ1603的略强化版,就是多了个不允许走回头路,我们把一条双向边建成两条方向相反的单向边,和网络流的建边一个方法,然后直接二维扫一遍建矩阵,a[i][j]=1表示从i号边下一步可以走到j号边,然后就做矩乘啦~然后再二维扫一遍出答案啦~然后笔者就妥妥的TLE啦~
当时看到TLE也是吓的不轻,实在是想不懂这种复杂度怎么会超时……然后就加了个读入优化顺便删掉iostream库再交上去:
这个故事告诉我们一个道理:刷八中不能用cin(这题用scanf一样过)
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
#define p 45989
const int maxn=150;
int n,m,k,s,t,x[maxn],y[maxn];
struct matrix{
int num[maxn][maxn];
void init(){
memset(num,0,sizeof num);
}
}a,ans;
int get(){
int s=0;char x=getchar();
while (x<'0' || x>'9') x=getchar();
while (x>='0' && x<='9') s=s*10+x-'0',x=getchar();
return s;
}
void init(){
n=get();m=get();k=get();s=get();t=get();
for (int i=0;i<m;i++){
x[i+i]=get();y[i+i]=get();
x[i+i+1]=y[i+i];y[i+i+1]=x[i+i];
}
m=m+m-1;
}
matrix operator *(matrix a,matrix b){
matrix c;c.init();
for (int i=0;i<=m;i++)
for (int j=0;j<=m;j++)
for (int t=0;t<=m;t++)
c.num[i][j]=(c.num[i][j]+a.num[i][t]*b.num[t][j])%p;
return c;
}
int main(){
init();
a.init();
for (int i=0;i<=m;i++)
for (int j=0;j<=m;j++)
if ((i^1)!=j && y[i]==x[j]) a.num[i][j]++;
for (int i=0;i<=m;i++) ans.num[i][i]=1;
for (k--;k;k>>=1,a=a*a)
if (k&1) ans=ans*a;
int calc=0;
for (int i=0;i<=m;i++)
for(int j=0;j<=m;j++)
if (x[i]==s && y[j]==t)
calc=(calc+ans.num[i][j])%p;
printf("%d\n",calc);
return 0;
}