【题解】
小规模图的连通性问题,可以用邻接矩阵+快速幂求解
本题唯一特殊的一点就是:
不能沿着刚刚走来的路走回,注意:不是不能走重边,而是不能反向走刚刚走过的边
处理方法是将无向边拆成两条有向边,互换点与边的地位,即:将两条有向边按是否首尾相接建立邻接矩阵
所有边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; }