1. 程式人生 > >【矩陣 && A 點到 B 點走 K 步的路徑條數(可以走重複邊) 】HDU

【矩陣 && A 點到 B 點走 K 步的路徑條數(可以走重複邊) 】HDU

Step1 Problem:

給你 n 個點,m 條邊的圖(有向),T 次詢問,對於每次詢問你 A 點到 B 點走K步的路徑條數(可以走重複邊)。
資料範圍:
0 < n <= 20, m <= 100, 1 <= T <= 100

Step2 Ideas:

我們知道 a->k 路徑數 x,k->b 路徑數 y,a->k->b 的路徑數 x*y。

Step3 Code:

#include<bits/stdc++.h>
using namespace std;
const int N = 25;
const
int mod = 1000; struct node { int a[N][N]; }; node c, ans; int n; node mul(node x, node y) { node ans; memset(ans.a, 0, sizeof(ans.a)); for(int k = 0; k < n; k++) { for(int i = 0; i < n; i++) { if(x.a[i][k]) for(int j = 0; j < n; j++) { ans.a[i][j] += x.a[i][k]*y.a[k][j]; ans.a[i][j] %= mod; } } } return
ans; } node Pow(node x, int m) { node ans; memset(ans.a, 0, sizeof(ans.a)); for(int i = 0; i < n; i++) ans.a[i][i] = 1; while(m) { if(m&1) ans = mul(ans, x); x = mul(x, x); m >>= 1; } return ans; } int main() { int m, u, v, step; while
(~scanf("%d %d", &n, &m) && (n||m)) { memset(c.a, 0, sizeof(c.a)); while(m--) { scanf("%d %d", &u, &v); c.a[u][v] = 1; } scanf("%d", &m); while(m--) { scanf("%d %d %d", &u, &v, &step); ans = Pow(c, step); printf("%d\n", ans.a[u][v]); } } return 0; }