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;
}

浙公网安备 33010602011771号