- 广度优先搜索+动态规划
Accepted 2157 0MS 1376K 1415B G++ #include "bits/stdc++.h" using namespace std; typedef pair<int, int> PII; const int MAXN = 25; const int MOD = 1000; // dp[i][j]表示固定起点后到达i走了j步的情况数 int dp[MAXN][MAXN]; bool mp[MAXN][MAXN]; queue<PII> que; int n, m; void BFS(int k) { while (!que.empty()) { int u = que.front().first; int w = que.front().second; que.pop(); if (w == k) { break; } for (int v = 0; v < n; v++) { if (mp[u][v] == false) continue; // 每个状态只能入队一次 if (dp[v][w + 1] == -1) { que.push({v, w + 1}); dp[v][w + 1] = 0; } dp[v][w + 1] = (dp[v][w + 1] + dp[u][w]) % MOD; } } while (!que.empty()) que.pop(); } int main() { int u, v, w; while (scanf("%d%d", &n, &m) && (n || m)) { memset(mp, false, sizeof(mp)); while (m--) { scanf("%d%d", &u, &v); mp[u][v] = true; } scanf("%d", &m); while (m--) { memset(dp, -1, sizeof(dp)); scanf("%d%d%d", &u, &v, &w); dp[u][0] = 1; que.push({u, 0}); BFS(w); if (dp[v][w] != -1) { printf("%d\n", dp[v][w]); } else { puts("0"); } } } return 0; }
对于本题比较快,但是如果w大了就不再适用,运行时间飙升。
- 矩阵快速幂 (看了大佬的代码之后敲的 https://www.cnblogs.com/hua-dong/p/7749902.html)
Accepted 2157 109MS 1392K 1016 B G++ #include "bits/stdc++.h" using namespace std; const int MOD = 1000; int n, m; struct Mat { int mat[25][25]; Mat() { memset(mat, 0, sizeof(mat)); } friend Mat operator * (Mat a, Mat b) { Mat c; for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) for(int k = 0; k < n; k++) c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % MOD; return c; } }; Mat Mat_pow(Mat m, int k) { Mat ans; for(int i = 0; i < n; i++) ans.mat[i][i] = 1; while(k) { if(k & 1) ans = ans * m; m = m * m; k >>= 1; } return ans; } int main() { int u, v, k; while (scanf("%d%d", &n, &m) && (n || m)) { Mat mp, ans; for (int i = 0; i < m; i++) { scanf("%d%d", &u, &v); mp.mat[u][v] = 1; } scanf("%d", &m); for (int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &k); ans = Mat_pow(mp, k); printf("%d\n", ans.mat[u][v]); } } return 0; }
对于本题,这份代码的复杂度高于上面那份,那是因为本题数据较小。如果k很大,矩阵快速幂的方法一定是比较优的。虽然会矩阵快速幂,还是没看出来mp就是可以得到结果的矩阵,果然还是菜了。慢慢积累吧。