제출 #1292019

#제출 시각아이디문제언어결과실행 시간메모리
1292019Hamed_Ghaffari철인 이종 경기 (APIO18_duathlon)C++20
큐에 대기중
0 ms0 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

#define mins(a, b) (a = min(a, b))
#define SZ(x) int(x.size())

const int MXN = 1e5+5;

int n, m;
int h[MXN], low[MXN], timer;
bool cut[MXN], CUT[MXN<<1];
vector<int> g[MXN], stk;
vector<vector<int>> comp;

void bcc(int v, int p=0) {
    low[v] = h[v] = ++timer;
    stk.push_back(v);
    for(int u : g[v]) if(u!=p) {
        if(h[u]) mins(low[v], h[u]);
        else {
            bcc(u, v);
            mins(low[v], low[u]);
            if(low[u]>=h[v]) {
                cut[v] |= h[v]>1 || h[u]>2;
                comp.push_back({v});
                while(comp.back().back()!=u) {
                    comp.back().push_back(stk.back());
                    stk.pop_back();
                }
            }
        }
    }
}

int N, id[MXN], cnt[MXN<<1];
vector<int> G[MXN<<1];

void block_cut_tree() {
    for(int i=1; i<=n; i++) {
        if(!h[i]) {
            bcc(i);
            if(g[i].empty()) {
                comp.push_back({i});
                stk.pop_back();
            }
        }
        if(cut[i]) {
            cnt[id[i]=++N]++;
            CUT[N] = 1;
        }
    }
    for(auto &cmp : comp) {
        N++;
        for(int v : cmp)
            if(cut[v])
                G[id[v]].push_back(N),
                G[N].push_back(id[v]);
            else cnt[id[v]=N]++;
    }
}

int sz[MXN<<1], par[MXN<<1];
vector<int> vec;
bool vis[MXN<<1];

void dfs(int v) {
    vec.push_back(v);
    vis[v] = 1;
    sz[v] = cnt[v];
    for(int u : G[v])
        if(!vis[u])
            par[u] = v,
            dfs(u),
            sz[v] += sz[u];
}

int32_t main() {
    cin.tie(0); cout.tie(0); ios_base::sync_with_stdio(0);
    cin >> n >> m;
    for(int i=1,u,v; i<=m; i++) {
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    block_cut_tree();
    ll ans = 0;
    for(int i=1; i<=N; i++)
        if(!vis[i]) {
            dfs(i);
            for(int v : vec) {
                ll tmp=0;
                int cur=sz[i]-sz[v];
                for(int u : G[v]) if(u!=par[v]) {
                    tmp += 1ll*cur*sz[u];
                    cur += sz[u];
                }
                ans += 2ll*cnt[v]*tmp;
                if(CUT[v]) {
                    for(int u : G[v]) {
                        ll c = cnt[u]+SZ(G[u])-1;
                        ans += 1ll*c*(c-1);
                    }
                }
                else {
                    ans += 2ll*cnt[v]*(cnt[v]-1)*(sz[i]-cnt[v]);
                    ans += 1ll*cnt[v]*(cnt[v]-1)*(cnt[v]-2);
                }
            }
            vec.clear();
        }
    cout << ans << '\n';
    return 0;
}