[SDOI2009]HH去散步(矩陣)
阿新 • • 發佈:2019-02-09
ems 矩陣乘法 c++ truct 輸入格式 限制 沒有 其中 max
題目描述
HH有個一成不變的習慣,喜歡飯後百步走。所謂百步走,就是散步,就是在一定的時間 內,走過一定的距離。 但是同時HH又是個喜歡變化的人,所以他不會立刻沿著剛剛走來的路走回。 又因為HH是個喜歡變化的人,所以他每天走過的路徑都不完全一樣,他想知道他究竟有多 少種散步的方法。
現在給你學校的地圖(假設每條路的長度都是一樣的都是1),問長度為t,從給定地 點A走到給定地點B共有多少條符合條件的路徑
輸入輸出格式
輸入格式:
第一行:五個整數N,M,t,A,B。其中N表示學校裏的路口的個數,M表示學校裏的 路的條數,t表示HH想要散步的距離,A表示散步的出發點,而B則表示散步的終點。
接下來M行,每行一組Ai,Bi,表示從路口Ai到路口Bi有一條路。數據保證Ai != Bi,但 不保證任意兩個路口之間至多只有一條路相連接。 路口編號從0到N − 1。 同一行內所有數據均由一個空格隔開,行首行尾沒有多余空格。沒有多余空行。 答案模45989。
輸出格式:
一行,表示答案。
輸入輸出樣例
輸入樣例#1: 復制4 5 3 0 0
0 1
0 2
0 3
2 1
3 2
輸出樣例#1: 復制
4
說明
對於30%的數據,N ≤ 4,M ≤ 10,t ≤ 10。
對於100%的數據,N ≤ 50,M ≤ 60,t ≤ 2^30,0 ≤ A,B
神題。。。
為限制不走上一次來的路和可以矩陣加速,花邊位點,一條邊和邊s連邊當接近當s^1不是自己,這樣以邊做矩陣乘法1次可以走兩步,t-1次走t步
1 #include <cstdio>
2 #include <algorithm>
3 #include <cstring>
4 #include"bits/stdc++.h"
5 #define Rep(i,s,t) for(int i=s;i<=t;i++)
6
7 using namespace std;
8
9 const int maxx = 120 + 5;
10 const int p = 45989;
11
12 int n,m,t,B,E,cnt=1,x,y,sum;
13 int head[maxx],nxt[maxx],to[maxx];
14
15 void Add(int x,int y){
16 nxt[++cnt]=head[x];to[cnt]=y;head[x]=cnt;
17 }
18
19 namespace matrix_mul{
20 struct mat{
21 int x[maxx][maxx];
22 mat(){memset(x,0,sizeof(x));}
23 };
24
25 mat mul(mat a,mat b){
26 mat tmp;Rep(i,1,m*2+1) Rep(j,1,m*2+1) Rep(k,1,m*2+1)
27 tmp.x[i][j] = (tmp.x[i][j]+a.x[i][k]*b.x[k][j])%p;
28 return tmp;
29 }
30
31 mat pwr(mat a,int n){
32 mat ans = a,tmp = a;n--;
33 while(n){if(n&1) ans=mul(ans,tmp);tmp=mul(tmp,tmp);n>>=1;}
34 return ans;
35 }
36 }
37
38 int main(){
39 using namespace matrix_mul;
40 mat Ans,tmp;
41 scanf("%d%d%d%d%d",&n,&m,&t,&B,&E);B++;E++;
42 Rep(i,1,m) scanf("%d%d",&x,&y),x++,y++,Add(x,y),Add(y,x);
43 for(int i=head[B];i;i=nxt[i]) Ans.x[1][i]=1;
44 for(int i=2;i<=cnt;i++)
45 for(int j=head[to[i]];j;j=nxt[j])
46 if(i != (j^1))
47 tmp.x[i][j]++;
48 tmp = pwr(tmp,t-1);
49
50
51 for(int i=head[B];i;i=nxt[i])
52 {
53 for (int j=2;j<=cnt;j++)if(to[j]==E)sum+=tmp.x[i][j],sum%=p;
54 }
55 cout<<sum<<endl;
56 return 0;
57
58 Ans = mul(Ans,tmp);
59
60
61 for(int i=2;i<=cnt;i++)
62 if(to[i]==E)
63 sum=(sum+Ans.x[1][i])%p;
64
65 printf("%d",sum);
66 return 0;
67 }
[SDOI2009]HH去散步(矩陣)