제출 #951674

#제출 시각아이디문제언어결과실행 시간메모리
951674abczz철인 이종 경기 (APIO18_duathlon)C++14
100 / 100
148 ms49088 KiB
#include <iostream>
#include <vector>
#include <algorithm>
#include <array>
#include <deque>
#include <queue>
#include <map>
#define ll long long

using namespace std;

bool visited[100000];
ll n, m, k, a, b, g, cnt, f, rt, apcnt, low[100000], st[100000], sz[200000], dp[200000];
vector <ll> G, blocks;
bool ap[100000];
vector <ll> V, adj[100000], X[100000], E[200000];

void tar(ll u, ll p) {
  G.push_back(u);
  st[u] = low[u] = ++cnt;
  V.push_back(u);
  ll rch = 0;
  for (auto v : adj[u]) {
    if (!st[v]) {
      ++rch;
      tar(v, u);
      low[u] = min(low[u], low[v]);
      if (p != -1 && low[v] >= st[u]) ap[u] = 1;
      if (low[v] >= st[u]) {
        blocks.push_back(k);
        while (!V.empty()) {
          auto x = V.back();
          V.pop_back();
          X[x].push_back(k);
          ++sz[k];
          if (x == v) break;
        }
        X[u].push_back(k);
        ++sz[k];
        ++k;
      }
    }
    else if (v != p) {
      low[u] = min(low[u], st[v]);
    }
  }
  if (p == -1 && rch > 1) ap[u] = 1;
}

void calc(ll u, ll p) {
  if (u >= n) dp[u] = sz[u] - E[u].size();
  else dp[u] = 1;
  //cout << u << " " << sz[u] << '\n';
  for (auto v : E[u]) {
    if (v != p) {
      calc(v, u);
      dp[u] += dp[v];
      if (u >= n) {
        f += (dp[v]-1) * (G.size() - dp[v]); //down -> ap -> up
        f += (dp[v]-1) * (sz[u] - E[u].size()) * (G.size() - dp[v] - 1); //edge -> nonap -> any
        f += (sz[u] - E[u].size()) * (G.size() - dp[v] - 1); //ap -> nonap -> any
        if (p != -1 && sz[u] > 2) {
          f += (dp[v]-1) * (E[u].size()-1) * (sz[u] - 2) * 2; //down -> ap -> down
        }
      }
    }
  }
  for (auto v : E[u]) {
    if (v != p) {
      if (u >= n) {
        if (p != -1 && sz[u] > 2 && E[u].size() > 2) {
          f += (dp[v]-1) * (dp[u]-sz[u]+1-(dp[v]-1)) * (E[u].size()-2); //downL -> ap -> downR
        }
      }
    }
  }
  if (u >= n) {
    if (p != -1 && E[u].size() > 2) f += (G.size() - dp[u] - 1) * (dp[u]-sz[u]+1) * (E[u].size() - 2) * 2;
    if (p != -1) f += (G.size() - dp[u] - 1) * dp[u]; //up -> ap -> down
    if (p != -1 && sz[u] > 2) {
      f += (G.size() - dp[u] - 1) * (sz[u] - 2) * (E[u].size()-1) * 2; //up -> ap -> up
    }
    if (sz[u] > 2) {
      f += (sz[u]-1) * (sz[u]-2) * E[u].size(); //down -> ap -> down & up -> ap -> up
    }
    f += (G.size() - dp[u] - (p != -1)) * (sz[u] - E[u].size()) * (dp[u] - 1); //topedge -> nonap -> any
    if (p != -1) f += (sz[u] - E[u].size()) * (dp[u] - 1); //ap -> nonap -> any
    if (G.size() >= 2) {
      f += (sz[u] - E[u].size()) * (sz[u] - (ll)E[u].size() - 1) * (G.size() - 2); //nonap -> nonap -> any
    }
  }
}

int main() {
  cin >> n >> m;
  for (int i=0; i<m; ++i) {
    cin >> a >> b;
    --a, --b;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  k = n;
  for (int i=0; i<n; ++i) {
    if (!st[i]) {
      G.clear();
      blocks.clear();
      V.clear();
      tar(i, -1);
      for (auto u : G) {
        if (ap[u]) {
          for (auto v : X[u]) {
            E[u].push_back(v);
            E[v].push_back(u);
          }
        }
      }
      if (!blocks.empty()) calc(blocks[0], -1);
    }
  }
  cout << f << '\n';
}
#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...