QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#585716 | #5437. Graph Completing | etherealUnicorn | RE | 59ms | 200660kb | C++14 | 3.0kb | 2024-09-23 21:53:58 | 2024-09-23 21:53:59 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
const int N = 5010;
const ll mod = 998244353;
vi G[N], Gbcc[N];
bool isBridge[N];
int fa[N], low[N], dfn[N], dfs_clock;
int bcc[N], cnt_bcc, bcc_sz[N], bcc_edge[N], tree_sz[N];
ll pow2[N * N], dp[N][N], tmpdp[N];
inline ll mAdd(ll x, ll y) { return (x + y) % mod; }
inline ll mDec(ll x, ll y) { return (x - y + mod) % mod; }
inline ll mMul(ll x, ll y) { return x * y % mod; }
void tarjan(int u);
void dfs(int u);
void init(int n, int m);
void solve(int u, int par);
int main()
{
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int n, m;
ll ans = 0;
cin >> n >> m;
init(n, m);
solve(1, 1);
assert(tree_sz[1] == n);
assert(dp[1][n - 1] != 0);
for (int i = bcc_sz[1]; i <= n; i++)
ans = mAdd(ans, dp[1][i]);
cout << ans << endl;
return 0;
}
void tarjan(int u)
{
dfs_clock++;
low[u] = dfn[u] = dfs_clock;
for (auto v : G[u])
{
if (!dfn[v])
{
fa[v] = u;
tarjan(v);
low[u] = min(low[u], low[v]);
if (low[v] > dfn[u])
isBridge[v] = true;
}
else if (dfn[v] < dfn[u] && v != fa[u])
low[u] = min(low[u], dfn[v]);
}
}
void dfs(int u)
{
bcc[u] = cnt_bcc;
bcc_sz[cnt_bcc]++;
for (auto v : G[u])
if (!isBridge[v])
{
if (v > u)
bcc_edge[cnt_bcc]++;
if (!bcc[v])
dfs(v);
}
}
void init(int n, int m)
{
pow2[0] = 1;
for (int i = 1; i < N * N; i++)
pow2[i] = mMul(2, pow2[i - 1]);
int u, v;
while (m--)
{
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
}
for (int i = 1; i <= n; i++)
if (!dfn[i])
tarjan(i);
for (int i = 1; i <= n; i++)
if (!bcc[i])
{
cnt_bcc++;
dfs(i);
}
for (int i = 1; i <= n; i++)
for (auto j : G[i])
if (bcc[j] != bcc[i])
Gbcc[bcc[i]].push_back(bcc[j]);
}
void solve(int u, int par)
{
dp[u][bcc_sz[u]] = pow2[bcc_sz[u] * (bcc_sz[u] - 1) / 2 - bcc_edge[u]];
int totsz = bcc_sz[u];
for (auto v : Gbcc[u])
if (v != par)
{
solve(v, u);
for (int i = bcc_sz[u]; i <= totsz; i++)
{
tmpdp[i] = dp[u][i];
dp[u][i] = 0;
}
for (int i = bcc_sz[u]; i <= totsz; i++)
for (int j = bcc_sz[v]; j <= tree_sz[v]; j++)
{
dp[u][i] = mDec(dp[u][i], mMul(tmpdp[i], dp[v][j]));
dp[u][i + j] = mAdd(dp[u][i + j], mMul(mMul(tmpdp[i], dp[v][j]), pow2[i * j - 1]));
}
totsz += tree_sz[v];
}
tree_sz[u] = totsz;
// for (int i = bcc_sz[u]; i <= totsz; i++)
// cout << "dp " << u << " " << i << " = " << dp[u][i] << endl;
}
详细
Test #1:
score: 100
Accepted
time: 59ms
memory: 200660kb
input:
3 2 1 2 2 3
output:
1
result:
ok 1 number(s): "1"
Test #2:
score: -100
Runtime Error
input:
4 4 1 2 2 3 3 4 4 1