제출 #1299335

#제출 시각아이디문제언어결과실행 시간메모리
1299335krit3379철인 이종 경기 (APIO18_duathlon)C++20
0 / 100
57 ms30164 KiB
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll<<60;
#define REP(i, n) for (ll i = 0; i < ll(n); i++)
template <class T>
using V = vector<T>;
template <class T>
using VV = V<V<T>>;
template <class A, class B>
bool chmax(A &a, B b){
    return a < b &&(a = b, true);
}
template <class A, class B>
bool chmin(A &a, B b){
    return b < a &&(a = b, true);
}

struct Biconnectivity{
    V<pair<int,int>> bct;
    V<int> tecc;
    int num_bcc,num_tecc;
    Biconnectivity(int n,const V<V<int>> &g):tecc(n){
        V<int> low(n),ord(n,-1),st(n),est(n+1,n);
        int it=0,idx=0,eit=0,f=0;
        auto dfs = [&](auto &dfs,int v,int p) -> void {
            st[it]=est[eit++]=v;
            low[v]=ord[v]=it++;
            for(int w:g[v])
            if(w!=p||!(p=-1)){
                if(ord[w]<0){
                    dfs(dfs,w,v);
                    low[v]=min(low[v],low[w]);
                    if(low[w]>=ord[v]){
                        while(ord[w]<it)
                            bct.push_back({idx,st[--it]});
                        bct.push_back({idx++,v});
                    }
                }
                low[v]=min(low[v],ord[w]);
            }  
            if(low[v]==ord[v]&&++f)
                while(est[eit]!=v)tecc[est[--eit]]=f-1;
        };
        REP(v,n)if(ord[v]<0)dfs(dfs,v,-1);
        REP(v,n)if(!g[v].size())bct.push_back({idx++,v});
        num_bcc=idx;
        num_tecc=f;
    }
      
};

void testcase(){
    int n,m;
    cin>>n>>m;
    if(!n)exit(0);
    
    V<V<int>> g(n);
    
    REP(i,m){
        int a,b; cin>>a>>b; a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    
    Biconnectivity bcc(n,g);
    
    auto bct=bcc.bct;
    
    int nn=n+bcc.num_bcc;
    
    V<V<int>> adj(nn);
    V<ll> cnt(nn);
    for(auto [idx,v]:bct){
        cnt[idx+n]++;
        adj[idx+n].push_back(v);
        adj[v].push_back(idx+n);
    }
    
    
    V<ll> dp1(nn),dp2(nn);
    
    ll ans=0;
    auto dfs = [&](auto &dfs,int s) -> void {
        
        ll choose=0;
        
        if(s>n)cnt[s]--;
        
        if(cnt[s]>1)choose=(cnt[s]-1)*(cnt[s]-1);
        if(cnt[s]>=3)ans+=cnt[s]*(cnt[s]-1)*(cnt[s]-2);
        
        for(auto x:adj[s]){
            adj[x].erase(find(adj[x].begin(),adj[x].end(),s));
            
            dfs(dfs,x);
            
            if(s>n)ans+=2*dp1[s]*dp1[x];
            ans+=2*cnt[s]*dp1[s]*dp1[x];
            ans+=2*dp1[x]*choose;
            ans+=2*cnt[s]*dp2[x];
            
            dp1[s]+=dp1[x];
            dp2[s]+=dp1[x]*cnt[s];
            dp2[s]+=dp2[x];
            
        }
        
        dp1[s]+=cnt[s];
        dp2[s]+=choose;

    };
    
    dfs(dfs,n);
    
    cout<<ans;
    
}

int main(){
    cin.tie(0)->sync_with_stdio(0);
    cout << fixed << setprecision(12);
    int t=1;
    // cin>>t;
    REP(_,t)testcase();
    
    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...