Submission #355981

# Submission time Handle Problem Language Result Execution time Memory
355981 2021-01-23T05:42:19 Z oolimry Duathlon (APIO18_duathlon) C++17
0 / 100
234 ms 46768 KB
#include <bits/stdc++.h>

using namespace std;
int n, m;
typedef vector<int> vi;
typedef pair<int,int> ii;
struct node{
  int depth = -1;
  int low;
  int parent;
  bool vis = false;
  bool isArti = false;
  vi adj;
};
vector<unordered_set<int> > biconnected;
stack<int> s; ///this is only needed for biconnected components
///note: this will ignore single nodes with no edges
static node g[200005];
int rootChildren = 0;
void dfs(int u){
  if(g[u].depth == -1) g[u].depth = g[g[u].parent].depth + 1;
  g[u].low = g[u].depth;
  g[u].vis = true;
  s.push(u);
  for(int i = 0;i < g[u].adj.size();i++){
    int v = g[u].adj[i];
    if(!g[v].vis){
      g[v].parent = u;
      if(g[u].depth == 0) rootChildren++;
      dfs(v);
      g[u].low = min(g[u].low,g[v].low);

      if(g[v].low >= g[u].depth){
        g[u].isArti = true;
        g[u].low = min(g[u].low,g[v].low);
        unordered_set<int> newSet;
        int nn;
        biconnected.push_back(newSet); ///create new biconnected component
        while(true){
          assert(!s.empty());
          nn = s.top();
          s.pop();
          biconnected.back().insert(nn);
          if(nn == v) break;
        }
      }
    }
    else if(v != g[u].parent){
      g[u].low = min(g[u].low,g[v].depth); ///g[v].depth not num!!!!!!
    }

  }
}
struct node2{
  long long sz;
  long long dp = 0;
  bool isArti = false;
  bool vis = false;
  int r;
  int p = -1;
  vi adj;
};

vector<node2> bct; ///block-cut tree
long long root = -1;
void dp(int u){
  if(bct[u].vis) return;
  bct[u].vis = true;
  bct[u].dp = bct[u].sz;
  bct[u].r = root;
  for(int i = 0;i < bct[u].adj.size();i++){
    int v = bct[u].adj[i];
    if(bct[v].vis) continue;
    bct[v].p = u;
    dp(v);
    bct[u].dp += bct[v].dp;
  }
}
int main()
{
  cin >> n >> m;
  ii edges[m];
  for(int i = 0;i < m;i++){
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    g[a].adj.push_back(b);
    g[b].adj.push_back(a);
    edges[i] = ii(a,b);
  }

  for(int i = 0;i < n;i++){
    if(!g[i].vis){
      rootChildren = 0;
      g[i].depth = 0;
      dfs(i);
      if(rootChildren > 1) g[i].isArti = true;
      else g[i].isArti = false; ///this line is needed
    }
  }
  unordered_map<int,int> artis;
  for(int i = 0;i < n;i++){
    if(g[i].isArti){
      artis[i] = bct.size();
      node2 nn;
      nn.sz = 1;
      nn.isArti = true;
      bct.push_back(nn);
    }
  }


  for(int i = 0;i < biconnected.size();i++){
    node2 nn;
    nn.sz = biconnected[i].size();
    nn.isArti = false;
    for(unordered_set<int>::iterator it = biconnected[i].begin();it != biconnected[i].end();it++){
      if(artis.find(*it) != artis.end()){
        nn.adj.push_back(artis[*it]);
        bct[artis[*it]].adj.push_back(bct.size());
        nn.sz--;
      }
    }
    bct.push_back(nn);
  }
  for(int i = 0;i < bct.size();i++){
    root = i;
    dp(i);
  }

  long long ans = 0ll;
  for(int i = 0;i < bct.size();i++){
    vector<long long> branches;
    vector<long long> branchStart;
    long long total = 0ll;
    for(int j = 0;j < bct[i].adj.size();j++){
      if(bct[i].adj[j] != bct[i].p){
        branches.push_back(bct[bct[i].adj[j]].dp);
        branchStart.push_back(bct[bct[i].adj[j]].sz);
      }
    }
    if(bct[i].p >= 0){
      branches.push_back(bct[bct[i].r].dp - bct[i].dp);
      branchStart.push_back(bct[bct[i].p].sz);
    }
    for(int j = 0;j < branches.size();j++) total += branches[j];
    long long extra = 0ll;
    if(!bct[i].isArti) extra = max(0ll,(long long)(bct[i].adj.size())-2);
    for(int j = 0;j < branches.size();j++){

      ///branch1 to self or neighbor articulation point to branch2
      ans += branches[j] * (total - branches[j]) * (bct[i].sz + extra);

      ///branch to self to self or self to self to branch
      ans += 2 * (bct[i].sz) * (bct[i].sz - 1) * branches[j];


      if(bct[i].isArti){
        ///direct branch to self to same branch(not reverse) or its reverse
        ans += 2ll * bct[i].sz * branchStart[j] * (branches[j] - branchStart[j]);
        ///direct branch to self to direct or its reverse
        ans += bct[i].sz * (branchStart[j]) * (branchStart[j] - 1);

      }
    }

    ///self to self to self
    ans += (bct[i].sz) * (bct[i].sz - 1) * (bct[i].sz - 2);
  }
  cout << ans;
}

Compilation message

count_triplets.cpp: In function 'void dfs(int)':
count_triplets.cpp:25:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   25 |   for(int i = 0;i < g[u].adj.size();i++){
      |                 ~~^~~~~~~~~~~~~~~~~
count_triplets.cpp: In function 'void dp(int)':
count_triplets.cpp:71:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   71 |   for(int i = 0;i < bct[u].adj.size();i++){
      |                 ~~^~~~~~~~~~~~~~~~~~~
count_triplets.cpp: In function 'int main()':
count_triplets.cpp:114:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::unordered_set<int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  114 |   for(int i = 0;i < biconnected.size();i++){
      |                 ~~^~~~~~~~~~~~~~~~~~~~
count_triplets.cpp:127:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<node2>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  127 |   for(int i = 0;i < bct.size();i++){
      |                 ~~^~~~~~~~~~~~
count_triplets.cpp:133:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<node2>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  133 |   for(int i = 0;i < bct.size();i++){
      |                 ~~^~~~~~~~~~~~
count_triplets.cpp:137:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  137 |     for(int j = 0;j < bct[i].adj.size();j++){
      |                   ~~^~~~~~~~~~~~~~~~~~~
count_triplets.cpp:147:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  147 |     for(int j = 0;j < branches.size();j++) total += branches[j];
      |                   ~~^~~~~~~~~~~~~~~~~
count_triplets.cpp:150:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  150 |     for(int j = 0;j < branches.size();j++){
      |                   ~~^~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Incorrect 6 ms 8172 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 6 ms 8172 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 169 ms 36208 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 7 ms 8556 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 226 ms 46768 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 7 ms 8556 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 234 ms 46768 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 6 ms 8172 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 6 ms 8172 KB Output isn't correct
2 Halted 0 ms 0 KB -