HH有个一成不变的习惯,喜欢饭后百步走。所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离。 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。 又因为HH是个喜欢变化的人,所以他每天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法。 现在给你学校的地图(假设每条路的长度都是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径
如果没有不能立刻走走过的路的限制是很水的矩阵乘法。
有了之后也不难,把f[i,n]表示第n个时刻在点i的方案数改成f[i,n]表示第n个时刻在边i的终点的方案数即可。
由于作死玩结构体重载运算符所以跑的飞慢。
#include<cstdio>
#include<algorithm>
#include<stack>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef int ll;
const int mo=45989;
int from[200],go[200];
stack<int> sta;
int i,j,k,l,s,t,n,m,tot,ans;
struct matrix{
ll a[200][200];
friend matrix operator *(matrix a,matrix b){
matrix c;
int i,j,k;
fo(i,1,tot)
fo(j,1,tot) c.a[i][j]=0;
fo(k,1,tot)
fo(i,1,tot)
fo(j,1,tot)
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%mo)%mo;
return c;
}
};
matrix a,dis,c,one,tt;
int main(){
scanf("%d%d%d%d%d",&n,&m,&l,&s,&t);
s++;t++;
tot=1;
from[1]=0;go[1]=s;
fo(i,1,m){
scanf("%d%d",&j,&k);
j++;k++;
from[++tot]=j;go[tot]=k;
from[++tot]=k;go[tot]=j;
}
fo(i,1,tot)
fo(j,1,tot)
if (i!=j&&(j^1)!=i&&go[j]==from[i]) dis.a[j][i]=1;
a.a[1][1]=1;
fo(i,1,tot) one.a[i][i]=1;
while (l){
sta.push(l%2);
l/=2;
}
tt=one;
while (!sta.empty()){
tt=tt*tt;
if (sta.top()==1) tt=tt*dis;
sta.pop();
}
dis=tt;
c=a*dis;
fo(i,1,tot)
if (go[i]==t) ans=(ans+c.a[1][i])%mo;
printf("%d\n",ans);
}