Submission #159453

#TimeUsernameProblemLanguageResultExecution timeMemory
159453MinnakhmetovDuathlon (APIO18_duathlon)C++14
31 / 100
132 ms21264 KiB
#include <bits/stdc++.h>
    
#define ll long long
#define all(aaa) aaa.begin(), aaa.end()
  
using namespace std;

const int N = 1e5 + 5;
vector<int> g2[N], t[N], g[N];
int tin[N], mt[N], col[N], sz[N], sum[N];
int timer = 0, n, m;
bool used[N];
 
void dfs(int node, int anc) {
    used[node] = 1;
    tin[node] = ++timer;
    mt[node] = tin[node];

    for (int to : g[node]) {
        if (to != anc) {
            if (!used[to]) {
                dfs(to, node);
            }
 
            mt[node] = min(mt[node], mt[to]);
 
            if (mt[to] <= tin[node]) {
                g2[node].push_back(to);
                g2[to].push_back(node);
            }
        }
    }
}
 
void deep(int node, int c) {
    col[node] = c;
    used[node] = 1;
 
    sz[col[node]]++;
 
    for (int to : g2[node]) {
        if (!used[to]) {
            deep(to, c);
        }
    }
 
    for (int to : g[node]) {
        if (used[to] && col[to] != col[node]) {
            t[col[node]].push_back(col[to]);
            t[col[to]].push_back(col[node]);
        }
    }
}
 
ll ans = 0;
 
int walk(int node, int anc) {
    int s = sz[node];
    for (int to : t[node]) {
        if (to != anc) {
            s += walk(to, node);
        }
    }
    return s;
}
 
void dive(int node, int anc, int whole) {
    ans += sz[node] * (ll)(sz[node] - 1) * (sz[node] - 2);
 
    sum[node] = sz[node];
 
    used[node] = 1;
 
    for (int to : t[node]) {
        if (to != anc) {
            dive(to, node, whole);
            sum[node] += sum[to];
        }
    }
 
    for (int to : t[node]) {
        int s = 0;
        if (to == anc)
            s = whole - sum[node];
        else
            s = sum[to];
 
        ans += sz[node] * (ll)s * (whole - s - sz[node]);
 
        ans += (sz[node] * (ll)(sz[node] - 1) - sz[node] + 1) * s * 2;
    }
}
 
signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
 
    cin >> n >> m;
 
    for (int i = 0; i < m; i++) {
        int a, b;
        cin >> a >> b;
        a--, b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }

    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            dfs(i, -1);
        }
    }
 
    int cc = 0;
 
    fill(used, used + n, 0);
 
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            deep(i, cc++);
        }
    }
 
    fill(used, used + cc, 0);
 
    for (int i = 0; i < cc; i++) {
        if (!used[i]) {
            dive(i, -1, walk(i, -1));
        }
    }
 
    cout << ans;
 
 
    return 0;
}
#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...