Submission #440077

#TimeUsernameProblemLanguageResultExecution timeMemory
440077VladMDuathlon (APIO18_duathlon)C++14
10 / 100
1090 ms1048580 KiB
#include <bits/stdc++.h>

using namespace std;

#define DIM 100007

long long res, cnt[2*DIM], sz[2*DIM], pnt[2*DIM], n, m, u, v, vis[2*DIM], used[2*DIM], tin[2*DIM], tmin[2*DIM], timer, comps;

set<long long> vec[2*DIM];

set<long long> p;

set<pair<long long, long long> > edge;

void dfs(long long v, long long par)
{
    used[v]=1;
    tin[v]=tmin[v]=++timer;
    long long ch_cnt=0;
    if(!vec[v].empty()) for(auto to : vec[v])
    {
        if(to==par) continue;
        if(used[to]==0)
        {
            dfs(to, v);
            ch_cnt++;
            tmin[v]=min(tmin[v], tmin[to]);
            if(par!=-1 && tmin[to]>=tin[v])
            {
                p.insert(v);
                pnt[v]=1;
            }
        }
        else tmin[v]=min(tmin[v], tin[to]);
    }
    if(par==-1 && ch_cnt>1)
    {
        p.insert(v);
        pnt[v]=1;
    }
    return;
}

void find_comp(long long v)
{
    vis[v]=comps;
    cnt[comps]++;
    if(vec[v].empty()) return;
    for(auto to : vec[v])
    {
        if(vis[to]!=0) continue;
        find_comp(to);
    }
    return;
}

void buildtree(long long v, long long par)
{
    if(v<=n) sz[v]+=1;
    else sz[v]+=cnt[v-n];
    if(vec[v].empty()) return;
    for(auto to : vec[v])
    {
        if(to==par) continue;
        sz[to]+=sz[v];
        buildtree(to, v);
    }
    return;
}

void get_res(long long v)
{
    for(int i=1; i<=2*n; i++) sz[i]=0;
    buildtree(v, -1);
    /*printf("%lld:\n", v);
    for(int i=1; i<=2*n; i++) printf("%lld ", sz[i]);
    printf("\n");*/
    if(!p.empty()) for(auto u : p)
    {
        if(sz[u]<2 || u==v) continue;
        res+=sz[v]*(sz[u]-2);
    }
    for(int i=1; i<=comps; i++)
    {
        if(sz[i+n]<2 || i+n==v) continue;
        res+=sz[v]*(sz[i+n]-2)*cnt[i];
    }
    long long ns=vec[v].size();
    for(int i=0; i<ns; i++)
    {
        res+=sz[v]*(sz[v]-1);
    }
    res+=sz[v]*(sz[v]-1)*(sz[v]-2);
    return;
}

int main()
{
    cin>>n>>m;
    for(int i=0; i<m; i++)
    {
        cin>>u>>v;
        vec[v].insert(u);
        vec[u].insert(v);
    }
    for(int i=1; i<=n; i++)
    {
        if(used[i]==0)
        {
            timer=0;
            dfs(i, -1);
        }
    }
    if(!p.empty()) for(auto v : p)
    {
        if(!vec[v].empty()) for(auto to : vec[v])
        {
            if(!vec[to].empty()) vec[to].erase(v);
            edge.insert({v, to});
        }
        if(!vec[v].empty()) vec[v].clear();
    }
    for(int i=1; i<=n; i++)
    {
        if(vis[i]==0 && pnt[i]==0)
        {
            comps++;
            find_comp(i);
        }
    }
    if(!edge.empty()) for(auto P : edge)
    {
        v=P.first;
        u=P.second;
        if(pnt[u])
        {
            vec[v].insert(u);
            vec[u].insert(v);
            continue;
        }
        vec[v].insert(vis[u]+n);
        vec[vis[u]+n].insert(v);
    }
    if(!p.empty()) for(auto u : p) get_res(u);
    for(int i=1; i<=comps; i++) get_res(i+n);
    cout<<res;
    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...