Description
HH有个一成不变的习惯,喜欢饭后百步走。所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离。 但
是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。 又因为HH是个喜欢变化的人,所以他每
天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法。 现在给你学校的地图(假设每条路的长度都
是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径
Input
第一行:五个整数N,M,t,A,B。
N表示学校里的路口的个数
M表示学校里的 路的条数
t表示HH想要散步的距离
A表示散步的出发点
B则表示散步的终点。
接下来M行
每行一组Ai,Bi,表示从路口Ai到路口Bi有一条路。
数据保证Ai != Bi,但不保证任意两个路口之间至多只有一条路相连接。
路口编号从0到N -1。
同一行内所有数据均由一个空格隔开,行首行尾没有多余空格。没有多余空行。
答案模45989。
N ≤ 20,M ≤ 60,t ≤ 2^30,0 ≤ A,B
Output
一行,表示答案。
Sample Input
4 5 3 0 0
0 1
0 2
0 3
2 1
3 2
0 1
0 2
0 3
2 1
3 2
Sample Output
4
第一道矩阵乘法……orz调了半天发现自己犯了一个傻逼错误
多余的不解释了,学习笔记里有思路。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #define MOD (45989) 6 using namespace std; 7 struct Mar 8 { 9 int a[201][201]; 10 } unit,G; 11 struct node1 12 { 13 int to,next; 14 } edge[10001]; 15 int n,head[10001],num_edge; 16 17 void add(int u,int v) 18 { 19 edge[num_edge].to=v; 20 edge[num_edge].next=head[u]; 21 head[u]=num_edge++; 22 } 23 24 Mar Mul(Mar x,Mar y) 25 { 26 Mar c; 27 memset(c.a,0,sizeof(c.a));//初始化,不然会GG 28 for (int i=0; i<=num_edge-1; ++i) 29 for (int j=0; j<=num_edge-1; ++j) 30 for (int k=0; k<=num_edge-1; ++k) 31 c.a[i][j]=(c.a[i][j]+x.a[i][k]*y.a[k][j])%MOD; 32 return c; 33 } 34 35 Mar Mar_pow(Mar a,int p) 36 { 37 Mar ans=unit; 38 while (p!=0) 39 { 40 if (p&1) 41 ans=Mul(ans,a); 42 a=Mul(a,a); 43 p>>=1; 44 } 45 return ans; 46 } 47 48 int main() 49 { 50 int m,t,st,ed,u,v; 51 scanf("%d%d%d%d%d",&n,&m,&t,&st,&ed); 52 ++st;++ed; 53 for (int i=1; i<=n; ++i) head[i]=-1; 54 for (int i=1; i<=m; ++i) 55 { 56 scanf("%d%d",&u,&v); 57 ++u;++v; 58 add(u,v);add(v,u); 59 } 60 for (int i=0; i<=num_edge-1; ++i) 61 unit.a[i][i]=1;//给单位矩阵赋值 62 for (int i=0; i<=num_edge-1; ++i) 63 for (int j=head[edge[i].to]; j!=-1; j=edge[j].next) 64 if ((i!=(j^1))) 65 G.a[i][j]++; 66 67 G=Mar_pow(G,t-1); 68 int Final=0; 69 for (int i=head[st]; i!=-1; i=edge[i].next) 70 for (int j=head[ed]; j!=-1; j=edge[j].next) 71 Final=(Final+G.a[i][j^1])%MOD;//异或就是将二进制最后一位取反,即入边变出边,出边变入边 72 printf("%d",Final); 73 }