제출 #926509

#제출 시각아이디문제언어결과실행 시간메모리
926509codefox철인 이종 경기 (APIO18_duathlon)C++14
66 / 100
157 ms42576 KiB
#include<bits/stdc++.h>

using namespace std;

#define int ll
#define ll long long
#define pii pair<int, int>

vector<vector<int>> graph;
vector<vector<pii>> cgraph;
vector<vector<ll>> opt;
vector<vector<int>> neigh;
vector<int> neighsum;
vector<vector<int>> asso;
vector<int> comp;
vector<int> low;
vector<int> num;
vector<int> vis;
vector<int> art;
vector<ll> compsize;
stack<int> s;
int root = -1;
ll sol = 0;
int c = 0;
int d = 0;
ll n, m;

void dfs(int i, int p)
{
    num[i] = low[i] = ++c;
    s.push(i);
    int sub = 0;
    int lastd = -1;
    for (int ele:graph[i])
    {
        if (ele == p) continue;
        if (!num[ele])
        {
            sub++;
            dfs(ele, i);
            if (low[ele]==num[i])
            {
                while(s.top() != ele)
                {
                    comp[s.top()] = d;
                    compsize[d]++;
                    asso[d].push_back(s.top());
                    s.pop();
                }
                comp[ele] = d;
                compsize[d]++;
                asso[d].push_back(ele);
                s.pop();
                lastd = d;
                d++;
            }
        }
        low[i] = min(low[i], low[ele]);
    }
    if (i==root && sub ==1 && lastd != -1)
    {
        art[lastd] = 1;
        compsize[lastd]++;
        comp[i] = lastd;
        s.pop();
        return;
    }
    if (num[i]==low[i])
    {
        art[d] = 1;
        while (s.top() != i)
        {
            comp[s.top()] = d;
            compsize[d]++;
            asso[d].push_back(s.top());
            s.pop();
        }
        asso[d].push_back(i);
        comp[i] = d;
        compsize[d]++;
        s.pop();
        d++;
    }
}

void dfs2(int i)
{
    vis[i] = 1;
    opt[i][0] = compsize[i];
    opt[i][1] = (compsize[i]-1)*(compsize[i]-2) +compsize[i]-1;
    if (!art[i]) opt[i][1] += compsize[i]-1;

    sol += (compsize[i]-2)*compsize[i]*(compsize[i]-1);
    if (!art[i]) sol += compsize[i]*(compsize[i]-1);
    vector<array<ll, 2>> ones;
    ll sum = 0;
    for (pii ele2:cgraph[i])
    {
        int ele = ele2.second;
        if (vis[ele]) continue;
        dfs2(ele);
        neigh[ele2.first].push_back(opt[ele][0]);
        neighsum[ele2.first]+=opt[ele][0];
        opt[i][0] += opt[ele][0];
        opt[i][1] += opt[ele][1] + opt[ele][0]*compsize[i];
        sum += opt[ele][0];
        ones.push_back({opt[ele][0], opt[ele][1]});
        sol += opt[ele][0]*(compsize[i]-1)*(compsize[i]-2)*2;
        sol += opt[ele][0]*(compsize[i]-1)*2;
        if (!art[i]) sol += opt[ele][0]*(compsize[i]-1)*2;
        sol += opt[ele][1]*compsize[i]*2;
    }

    for (array<ll, 2> ele:ones)
    {
        if (!art[i]) sol += ele[0]*(sum-ele[0])*(compsize[i]+1);
        else         sol += ele[0]*(sum-ele[0])*(compsize[i]);
        sol += ele[1]*(sum-ele[0])*2;
    }
    for (int ele:asso[i])
    {
        for (int ele2:neigh[ele])
        {
            if (!art[i]) sol -= ele2*(neighsum[ele]-ele2)*(compsize[i]);
            else sol -= ele2*(neighsum[ele]-ele2)*(compsize[i]-1);
        }
    }
}

int32_t main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    cin >> n >> m;
    graph.assign(n, vector<int>());
    cgraph.assign(n, vector<pii>());
    neigh.assign(n, vector<int>());
    asso.assign(n, vector<int>());
    neighsum.assign(n, 0);
    compsize.assign(n, 0);
    low.assign(n, 0);
    num.assign(n, 0);
    comp.assign(n, -1);
    vis.assign(n, 0);
    art.assign(n, 0);
    opt.assign(n, vector<ll>(2, 0));

    for (int i =0; i < m; i++)
    {
        int a, b;
        cin >> a >> b;
        a--; b--;
        graph[a].push_back(b);
        graph[b].push_back(a);
    }

    for (int i =0; i < n; i++)
    {
        if (!num[i])
        {
            root = i;
            dfs(i, -1);
        }
    }

    for (int i = 0; i <n; i++)
    {
        for (int ele:graph[i])
        {
            if (comp[i] == comp[ele]) continue;
            cgraph[comp[i]].push_back({i, comp[ele]});
        }
    }

    for (int i = 0; i< n; i++)
    {
        if (!vis[comp[i]])
        {
            dfs2(comp[i]);
        }
    }

    cout << sol << "\n";

    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...