【题解】
小规模图的连通性问题,可以用邻接矩阵+快速幂求解
本题唯一特殊的一点就是:
不能沿着刚刚走来的路走回,注意:不是不能走重边,而是不能反向走刚刚走过的边
处理方法是将无向边拆成两条有向边,互换点与边的地位,即:将两条有向边按是否首尾相接建立邻接矩阵
所有边Ei:u->v与Ej:v->w(w!=u),都有 Y[i][j]=1
此时Y[i][j]=1的意义是:从边i的末端走一步能到达边j的末端,有1种方案
由于 Y[i][ i的反向边 ]==0,所以避免了"沿着刚刚走来的路走回"的情况
只需将这个矩阵自乘t-1次,Y[i][j]就代表从边i的始端走t步到达边j的末端的方案数,自乘的原理是乘法原理
又因为起点规定好是A,再构造一个系数矩阵X,使其与Y相乘后仅保留Y[i][j]中i的起点是A的位置,累加终点是B的边j的答案即可
【代码】
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MOD 45989
int v[125],first[25],next[125];
int e=0;
struct juzhen
{
int s[125][125];
juzhen()
{
memset(s,0,sizeof(s));
}
};
juzhen cheng(juzhen a,juzhen b)
{
juzhen res;
int i,j,k;
for(i=1;i<=e;i++)
for(j=1;j<=e;j++)
{
for(k=1;k<=e;k++)
res.s[i][j]+=a.s[i][k]*b.s[k][j]%MOD;
res.s[i][j]%=MOD;
}
return res;
}
juzhen ksm(juzhen a,int n)
{
juzhen res;
if(n==1) return a;
res=ksm(a,n/2);
res=cheng(res,res);
if(n&1) res=cheng(res,a);
return res;
}
void tj(int x,int y)
{
v[++e]=y;
next[e]=first[x];
first[x]=e;
}
int fan(int x)
{
if(x&1) return x+1;
return x-1;
}
int main()
{
juzhen X,Y;
int n,m,t,A,B,i,j,x,y,ans=0;
scanf("%d%d%d%d%d",&n,&m,&t,&A,&B);
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
tj(x,y);
tj(y,x);
}
for(i=first[A];i!=0;i=next[i])//构造系数矩阵
X.s[1][i]=1;
if(t==0)
{
if(A==B) printf("1");
printf("0");
}
else
{
if(t>1)
{
for(i=1;i<=e;i++)
for(j=first[v[i]];j!=0;j=next[j])
if(j!=fan(i)) Y.s[i][j]=1;
X=cheng(X,ksm(Y,t-1));
}
for(i=first[B];i!=0;i=next[i])
ans+=X.s[1][fan(i)];//边fan(i)的终点是B
}
printf("%d",ans%MOD);
return 0;
}