Codeforces
CF Step
Youtube Linkedin Discord Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Code : Swap on Tree

#include <atcoder/modint>
#include <bits/stdc++.h>

using namespace std;
using namespace atcoder;

using mint = modint998244353;

class Tree {
  public:
    int n;
    vector<vector<int>> adj;
    vector<vector<mint>> dp;
    // dp[i][d] represents the sum of cost of configurations of the i-th subtree
    // in which the i-th node has degree d.
    Tree(int n) {
        this->n = n;
        adj.resize(n);
        dp.resize(n, vector<mint>(n + 1, 0));
    }

    void dfs(int src, int par) {
        dp[src][0] = 1;
        for (auto child : adj[src]) {
            if (child == par) {
                continue;
            }
            dfs(child, src);
            vector<mint> ndp(n + 1);
            for (int d = 0; d < adj[src].size(); d++) {
                for (int now = 0; now < adj[child].size(); now++) {
                    ndp[d] += dp[src][d] * dp[child][now];
                    ndp[d + 1] +=
                        dp[src][d] * dp[child][now] * (d + 1) * (now + 1);
                }
            }
            swap(dp[src], ndp);
        }
    }
};

void solve() {
    int n;
    cin >> n;
    Tree t(n);

    int m = n - 1;
    for (int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        x--;
        y--;
        t.adj[x].push_back(y);
        t.adj[y].push_back(x);
    }

    t.dfs(0, -1);
    mint ans = 0;
    for (int d = 0; d < n; d++) {
        ans += t.dp[0][d];
    }
    cout << ans.val() << endl;
}

int main() {
    int t;
    // Set t = 1 while submitting on Atcoder.
    cin >> t;
    for (int i = 0; i < t; i++) {
        solve();
    }
    return 0;
}
#include <atcoder/modint>
#include <bits/stdc++.h>

using namespace std;
using namespace atcoder;

using mint = modint998244353;

class Tree {
  public:
    int n;
    vector<vector<int>> adj;
    vector<int> deg;
    vector<bool> visited;
    Tree(int n) {
        this->n = n;
        adj.resize(n);
        deg.resize(n);
        visited.resize(n);
    }

    void dfs(int src, int par) {
        if (visited[src]) {
            return;
        }

        deg[src] = adj[src].size();
        for (auto child : adj[src]) {
            if (child != par) {
                dfs(child, src);
            }
        }
    }
};

void solve() {
    int n;
    cin >> n;

    vector<mint> fac(n + 2);
    fac[0] = 1;
    for (int i = 1; i < n + 2; i++) {
        fac[i] = i * fac[i - 1];
    }

    vector<pair<int, int>> edges;
    int m = n - 1;
    for (int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        x--;
        y--;
        edges.push_back({x, y});
    }

    mint ans = 0;

    int full_mask = 1 << m;
    for (int msk = 0; msk < full_mask; msk++) {
        Tree t(n);
        for (int i = 0; i < m; i++) {
            if ((1 << i) & msk) {
                int x = edges[i].first;
                int y = edges[i].second;
                t.adj[x].push_back(y);
                t.adj[y].push_back(x);
            }
        }
        mint now = 1;
        for (int i = 0; i < n; i++) {
            t.dfs(i, -1);
            now *= fac[t.deg[i]];
        }
        ans += now;
    }

    cout << ans.val() << endl;
}

int main() {
    int t;
    // Set t = 1 while submitting on Atcoder.
    cin >> t;
    for (int i = 0; i < t; i++) {
        solve();
    }
    return 0;
}