QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#585716#5437. Graph CompletingetherealUnicornRE 59ms200660kbC++143.0kb2024-09-23 21:53:582024-09-23 21:53:59

Judging History

你现在查看的是最新测评结果

  • [2024-09-23 21:53:59]
  • 评测
  • 测评结果:RE
  • 用时:59ms
  • 内存:200660kb
  • [2024-09-23 21:53:58]
  • 提交

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

output:


result: