洛谷 4159 SCOI2009 迷路

2021-09-28 22:00:09 字數 1693 閱讀 7026

題目描述

windy在有向圖中迷路了。 該有向圖有 n 個節點,windy從節點 0 出發,他必須恰好在 t 時刻到達節點 n-1。 現在給出該有向圖,你能告訴windy總共有多少種不同的路徑嗎? 注意:windy不能在某個節點逗留,且通過某有向邊的時間嚴格為給定的時間。

輸入格式

第一行包含兩個整數,n t。 接下來有 n 行,每行乙個長度為 n 的字串。 第i行第j列為』0』表示從節點i到節點j沒有邊。 為』1』到』9』表示從節點i到節點j需要耗費的時間。

輸出格式

包含乙個整數,可能的路徑數,這個數可能很大,只需輸出這個數除以2009的餘數。

輸入輸出樣例

輸入 #1

2 211

00

輸出 #1

1

輸入 #2

5 30

12045

07105

47805

12024

12345

輸出 #2

852

說明/提示

【樣例解釋一】

0->0->1

【資料範圍】

30%的資料,滿足 2 <= n <= 5 ; 1 <= t <= 30 。

100%的資料,滿足 2 <= n <= 10 ; 1 <= t <= 1000000000 。

解釋:如果邊都是1的話,很簡單,所以我們就想辦法把它轉行成邊為1,我們對每個點進行擴充到9個,這樣的話,每條邊長為1,得到矩陣後直接矩陣快速冪即可。

#include#include#include#define n 120

#define mod 2009

#define ll int

using namespace std;

int g[n][n]=;

int n=0,t=0;

int m=0;

char str[123];

class matrix

int get(int x,int y)

void set(int x,int y,int val)

void mul(matrix &b);

for(int i=1;i<=n;i++)}}

for(int i=1;i<=n;i++)

for(int j=1;j<=n;j++) a[i][j]=c[i][j];

}void pow(ll k)k>>=1;

this->mul(*this);

}for(int i=1;i<=n;i++)

for(int j=1;j<=n;j++) a[i][j]=ret.a[i][j]%mod;

}void display()

printf("\n");}}

};int main()

g[pos][(j-1)*9+1]=1;}}

for(int i=1;i<=m;i++) for(int j=1;j<=m;j++) mk.a[i][j]=g[i][j];

mk.pow(t);

cout

}

洛谷 P4159 SCOI2009 迷路

如果邊權為 1 11,則是簡單的矩陣快速冪加速dp遞推方程,又因為邊權並不大,所以考慮拆點,新圖中邊權均為 1 11,將每個點暴力拆成相連的 9 99 個點,對於原先某條邊 u,v,w u,v,w u,v,w 可以轉化為 u uu 拆成的點中第 w ww 個連向 v vv 拆成的點中第 1 11 個...

洛谷 P4159 SCOI2009 迷路

windy在有向圖中迷路了。該有向圖有 n 個節點,windy從節點 0 出發,他必須恰好在 t 時刻到達節點 n 1。現在給出該有向圖,你能告訴windy總共有多少種不同的路徑嗎?注意 windy不能在某個節點逗留,且通過某有向邊的時間嚴格為給定的時間。根據題意,可以寫出轉移方程 f sum f ...

題解 P4159 SCOI2009 迷路

large 題目和普通的 01 路徑矩陣加速有一點區別,做法很巧。large 給定乙個鄰接矩陣,即每個點之間的邊權,若為 0 則無邊,因為是 a a 的矩陣,所以隱藏含義是每條邊權 1 9 large 因為邊權不只是 1 了,所以不能直接就將每個點連線邊做矩乘,但是資料範圍太大又不能不用矩乘。注意到...