0x3F
2023-03-24 23:31:35
有时候我们应当对自己有信心,
考虑一个显而易见的容斥:枚举边集的一个大小为
考虑使用 dfs,若前
考虑一个剪枝:如果一条边加入以后连通性完全没有改变,那么直接返回
理论时间复杂度
代码如下:
#include <bits/stdc++.h>
using namespace std;
int n, m, k, p[40], u[40], v[40], f[40];
int find(int x) {
if (x == f[x]) return x;
return find(f[x]);
}
int dfs(int i, int c) {
if (i == m+1) return p[c];
int x = find(u[i]);
int y = find(v[i]);
if (x == y) return 0;
int f1 = dfs(i+1, c);
f[y] = x;
int f2 = dfs(i+1, c-1);
f[y] = y;
return (f1 - f2 + 998244353) % 998244353;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
mt19937 rng;
uniform_int_distribution<int> randombool(0, 1);
cin >> n >> m >> k;
p[0] = 1;
for (int i = 1; i <= n; i++) {
p[i] = (long long) p[i-1] * k % 998244353;
}
for (int i = 1; i <= m; i++) {
cin >> u[i] >> v[i];
if (randombool(rng) & 1) swap(u[i], v[i]);
}
for (int i = 1; i <= n; i++) {
f[i] = i;
}
cout << dfs(1, n) << endl;
return 0;
}
后记:赛时最大运行时间大约是 7.7s
。
这次