[bzoj1875] [洛谷P2151] [SDOI2009] HH去散步
阿新 • • 發佈:2018-03-13
完全 空格 AC algorithm mar () desc init 什麽
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
Sample Output
4
想法
數據範圍提示我用矩陣乘法。
其中每個點表示一條路而不是一個點。
然後好像沒什麽可說的了。。。。
代碼
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #define P 45989 using namespace std; typedef long long ll; const int SZ = 140; int n,m; struct matrix{ ll a[SZ][SZ]; matrix() { memset(a,0,sizeof(a)); } void init() { for(int i=0;i<SZ;i++) a[i][i]=1; } matrix operator * (const matrix &b) const{ matrix c; for(int i=0;i<m;i++) for(int j=0;j<m;j++) for(int k=0;k<m;k++) (c.a[i][j]+=a[i][k]*b.a[k][j])%=P; return c; } matrix operator *= (const matrix &b) { return *this=*this*b; } }; matrix Pow_mod(matrix x,ll y){ matrix ret; ret.init(); while(y){ if(y&1) ret*=x; x*=x; y>>=1; } return ret; } struct edge{ int fr,to; }e[140]; int A,B; ll t; int main() { int u,v; scanf("%d%d%lld%d%d",&n,&m,&t,&A,&B); for(int i=0;i<m;i++){ scanf("%d%d",&u,&v); e[i*2].fr=u; e[i*2].to=v; e[i*2+1].fr=v; e[i*2+1].to=u; } m*=2; matrix a,b; for(int i=0;i<m;i++) if(e[i].fr==A) b.a[0][i]=1; for(int i=0;i<m;i++) for(int j=0;j<m;j++) if(e[i].to==e[j].fr){ if(i/2==j/2) continue; a.a[i][j]=1; } a=Pow_mod(a,t-1); b=b*a; ll ans=0; for(int i=0;i<m;i++) if(e[i].to==B) (ans+=b.a[0][i])%=P; printf("%lld\n",ans); return 0; }
[bzoj1875] [洛谷P2151] [SDOI2009] HH去散步