AtCoder Beginner Contest 212 [E - Safety Journey]
题意:给定一张无向完全图,从中打断几条边,问从原点出发经过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;
}

浙公网安备 33010602011771号