Submission #676239

#TimeUsernameProblemLanguageResultExecution timeMemory
676239danikoynovDuathlon (APIO18_duathlon)C++14
100 / 100
223 ms34608 KiB
/**
 ____ ____ ____ ____ ____ ____
||l |||e |||i |||n |||a |||d ||
||__|||__|||__|||__|||__|||__||
|/__\|/__\|/__\|/__\|/__\|/__\|

**/

#include<bits/stdc++.h>
#define endl '\n'

using namespace std;
typedef long long ll;

void speed()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
}

const int maxn = 2e5 + 10;

int n, m, tin[maxn], low[maxn], timer, bcc, cnt;
vector < int > g[maxn * 2], bcc_graph[maxn];
stack < int > st;

void add_edge(int v, int u)
{
    bcc_graph[v].push_back(u);
    bcc_graph[u].push_back(v);
}

void dfs(int v, int p)
{
    tin[v] = low[v] = ++ timer;
    st.push(v);
    ///cout << "enter " << v << " " << tin[v] << endl;
    cnt ++;
    for (int u : g[v])
    {
        if (u == p)
            continue;
        if (tin[u])
        {
            low[v] = min(low[v], tin[u]);
        }
        else
        {
            dfs(u, v);
            low[v] = min(low[v], low[u]);
            if (low[u] >= tin[v])
            {
                ///cout << v << " : " << u << endl;
                bcc ++;
                add_edge(v, n + bcc);
                while(st.top() != u)
                {
                    add_edge(st.top(), n + bcc);
                    ///cout << st.top() << endl;
                    st.pop();
                }
                add_edge(st.top(), n + bcc);
                st.pop();
            }
        }
    }
}


ll ans = 0;
ll sub[maxn];
void bad_triple(int v, int p)
{
    if (v <= n)
        sub[v] = 1;
    for (int u : bcc_graph[v])
    {
        if (u == p)
            continue;
        bad_triple(u, v);
        sub[v] += sub[u];
        if (v > n)
        {
            ans = ans - (ll)((ll)bcc_graph[v].size() - 1) * (ll)(sub[u]) *(ll)(sub[u] - 1);
            ///cout << v << " : " << u << " " << sub[u] << " " << (ll)((ll)bcc_graph[v].size() - 1) * (ll)(sub[u]) *(ll)(sub[u] - 1) << endl;
        }
    }
    if (v > n)
    {
        ans = ans - (ll)((ll)bcc_graph[v].size() - 1) * (ll)(cnt - sub[v]) * (ll)(cnt - sub[v] - 1);
    }

}
void solve()
{
    cin >> n >> m;
    for (int i = 1; i <= m; i ++)
    {
        int v, u;
        cin >> v >> u;
        g[v].push_back(u);
        g[u].push_back(v);
    }

    for (int i = 1; i <= n; i ++)
    {
        if (tin[i])
            continue;
        cnt = 0;
        dfs(i, 0);

        ans += (ll)(cnt) * (ll)(cnt - 1) * (ll)(cnt - 2);
        bad_triple(i, 0);
    }

    cout << ans << endl;

}

int main()
{
    solve();
    return 0;
}

/**
10 30
5 6
9 5
4 9
6 7
7 9
10 3
7 5
10 6
4 2
6 2
5 2
7 3
8 1
8 3
4 5
3 1
9 6
7 8
4 1
2 3
4 10
1 7
2 8
4 8
7 2
9 2
9 3
10 2
2 1
8 10

*/
#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...