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;
}
posted @ 2021-08-01 22:06  0xYuk1  阅读(70)  评论(0)    收藏  举报