AtCoder Beginner Contest 212 [E - Safety Journey]
阿新 • • 發佈:2021-08-02
題意:給定一張無向完全圖,從中打斷幾條邊,問從原點出發經過k步之後能夠回到原點的方案有幾種。
解題思路:看到題第一眼就想到矩陣乘法,火速寫了一發,結果喜提TLE,那麼重新看這道題,題目範圍有5000,因此通過\(n^3\)的矩陣快速冪去求解顯然不現實,那麼重新從DP的角度去看這道題,將\(dp[i][j]\)表示為第i步到達j點的方案數,由於是一張無向完全圖,所到的沒一點都可以由上一次可以到的全部點到達,於是我們可以有此得出遞推方程
\[dp[i+1][j] = \sum_{j'=1} ^ N dp[i][j'] - \sum_{j'∈S_j} dp[i][j'] \]解題程式碼:
#include <bits/stdc++.h> #define int long long using namespace std; const int maxn = 5000 + 10; const int mod = 998244353; vector<int>e[maxn]; int dp[maxn]; int dp2[maxn]; signed main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int n,m,k,u,v; cin >> n >> m >> k; for(int i = 0;i < m;i++){ int u,v; cin >> u >> v; e[u - 1].push_back(v - 1); e[v - 1].push_back(u - 1); } dp[0] = 1ll; for(int i = 1;i <= k;i++){ int sum = 0; for(int j = 0;j < n;j++)sum += dp[j]; for(int j = 0;j < n;j++){ dp2[j] = sum - dp[j]; for(auto t:e[j]) dp2[j] -= dp[t]; dp2[j] %= mod; } for(int j = 0;j < n;j++)dp[j] = dp2[j]; } cout << dp[0] << endl; return 0; }