Submission #546796

#TimeUsernameProblemLanguageResultExecution timeMemory
546796MonarchuwuDuathlon (APIO18_duathlon)C++17
31 / 100
62 ms10704 KiB
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;

const int N = 1e5 + 9;
int n, m;
vector<int> g[N];

// chain and cycle
namespace subtask3 {
    bool check() {
        for (int i = 1; i <= n; ++i)
            if (g[i].size() > 2) return false;
        return true;
    }

    int par[N];
    int root(int u) { return par[u] < 0 ? u : par[u] = root(par[u]); }
    void Union(int u, int v) {
        if ((u = root(u)) == (v = root(v))) return;
        if (par[u] > par[v]) swap(u, v);
        par[u] += par[v];
        par[v] = u;
    }

    bool f[N];
    void solve() {
        fill(par + 1, par + n + 1, -1);
        for (int u = 1; u <= n; ++u)
            for (int v : g[u]) Union(u, v);

        for (int i = 1; i <= n; ++i)
            if (g[i].size() == 1) f[root(i)] = true;

        ll ans(0), sz;
        for (int i = 1; i <= n; ++i) if (par[i] < 0) {
            sz = -par[i];
            ans += sz * (sz - 1) * (sz - 2) / (f[i] ? 3 : 1);
        }
        cout << ans << '\n';
    }
}

// tree
namespace subtask45 {
    int par[N];
    int root(int u) { return par[u] < 0 ? u : par[u] = root(par[u]); }
    bool Union(int u, int v) {
        if ((u = root(u)) == (v = root(v))) return false;
        if (par[u] > par[v]) swap(u, v);
        par[u] += par[v];
        par[v] = u;
        return true;
    }
    bool check() {
        fill(par + 1, par + n + 1, -1);
        for (int u = 1; u <= n; ++u)
            for (int v : g[u])
                if (u < v && !Union(u, v)) return false;
        return true;
    }

    ll ans;
    int sz[N];
    bool vis[N];
    void dfs_sz(int u, int p) {
        sz[u] = 1;
        for (int v : g[u]) if (v != p) {
            dfs_sz(v, u);
            sz[u] += sz[v];
        }
    }
    void dfs(int u, int p, int sz_n) {
        vis[u] = true;
        ans += (ll)(sz_n - sz[u]) * (sz[u] - 1) * 2;
        ll sum(0);
        for (int v : g[u]) if (v != p) {
            ans += sum * sz[v] * 2;
            sum += sz[v];
            dfs(v, u, sz_n);
        }
    }
    void solve() {
        for (int u = 1; u <= n; ++u) if (!vis[u]) {
            dfs_sz(u, 0);
            dfs(u, 0, sz[u]);
        }
        cout << ans << '\n';
    }
}

bool f[N];
int main() {
    cin.tie(NULL)->sync_with_stdio(false);
    cin >> n >> m;
    for (int i = 0, u, v; i < m; ++i) {
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }

    if (subtask3::check())
        subtask3::solve();
    else if (subtask45::check())
        subtask45::solve();
}
/**  /\_/\
 *  (= ._.)
 *  / >0  \>1
**/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...