BZOJ 1875 SDOI2009 HH去散步
1875: [SDOI2009]HH去散步
Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 2018 Solved: 994
[Submit][Status][Discuss]
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
HINT
Source
注意矩阵乘法不满足交换律
#include <bits/stdc++.h> #define ll long long using namespace std; inline int read(){ int x=0;int f=1;char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} return x*f; } const int MOD=45989; const int MAXN=10000; namespace zhangenming{ struct node{ int x,y; }e[MAXN]; struct Martrix{ int martrix[130][130]; }ans,x,st; int n,m,A,B,t,M,anss[MAXN],ans_top=0; void init(){ n=read();m=read();t=read();A=read();B=read(); for(int i=1;i<=m;i++){ e[i].x=read(); e[i].y=read(); if(e[i].x==B) anss[++ans_top]=i+m; if(e[i].y==B) anss[++ans_top]=i; } for(int i=1;i<=m;i++){ for(int j=1;j<=m;j++){ if(i==j) continue; if(e[i].y==e[j].x) x.martrix[i][j]=1; if(e[i].x==e[j].x) x.martrix[i+m][j]=1; if(e[i].y==e[j].y) x.martrix[i][j+m]=1; if(e[i].x==e[j].y) x.martrix[i+m][j+m]=1; } if(e[i].x==A) st.martrix[1][i]=1; if(e[i].y==A) st.martrix[1][i+m]=1; } } void operator *= (Martrix &x,Martrix y){ Martrix z; memset(&z,0,sizeof(z)); for(int i=1;i<=M;i++){ for(int j=1;j<=M;j++){ for(int k=1;k<=M;k++){ z.martrix[i][j]+=x.martrix[i][k]*y.martrix[k][j]; z.martrix[i][j]%=MOD; } } } x=z; } void print(Martrix &a){ for(int i=1;i<=M;i++){ for(int j=1;j<=M;j++){ cout<<a.martrix[i][j]<<' '; } cout<<endl; } cout<<endl; } void ksm(int k){ while(k){ if(k&1) ans*=x; x*=x; k>>=1; } st*=ans; } void solve(){ M=m+m; for(int i=1;i<=M;i++){ ans.martrix[i][i]=1; } ksm(t-1); ll tot=0; for(int i=1;i<=ans_top;i++){ tot+=st.martrix[1][anss[i]]; tot%=MOD; } cout<<tot<<endl; } } int main(){ using namespace zhangenming; init(); solve(); return 0; }