CSES - TCR Contest - Results
Submission details
Task:Graph Cutting
Sender:Hannes Ihalainen
Submission time:2017-11-21 18:35:44 +0200
Language:C++
Status:READY
Result:ACCEPTED
Test results
testverdicttime
#1ACCEPTED0.16 sdetails

Code

#include <bits/stdc++.h>
#define F first
#define S second
#define MP make_pair
using namespace std;
int n, m;

struct Bridges{
  vector<int> c, h;
  void dfs(vector<pair<int, int> >* g, int x, int pe, int d, vector<int>& ns){
    if (h[x]) return;
    h[x]=d; ns.push_back(x);
    for (auto nx : g[x]){
      if (nx.S!=pe){
        dfs(g, nx.F, nx.S, d+1, ns);
        h[x]=min(h[x], h[nx.F]);
      }
    }
    if (h[x]==d){
      while (ns.size()>0){
        int t=ns.back();c[t]=x;
        ns.pop_back();
        if (t==x) break;
      }
    }
  }
  Bridges(vector<pair<int, int> >*g, int n) : c(n+1), h(n+1){
    vector<int> ns;
    for (int i=1; i<=n; ++i) dfs(g, i, -1, 1, ns);
  }
};

struct Biconnected{
  vector<int> cut, h, d, used;
  vector<map<int, vector<int> > > bg;
  vector<pair<int, int> > es;
  int cc;
  void dfs(vector<int>* g, int x, int p) {
    h[x]=d[x];
    int f=0;
    for (int nx:g[x]){
      if (nx!=p){
        if (!used[nx]) es.push_back({x, nx});
        if (d[nx]==0){
          ++f; d[nx]=d[x]+1;
          int ts=es.size();
          dfs(g, nx, x);
          h[x]=min(h[x], h[nx]);
          if (h[nx]>=d[x]){
            cut[x]=1;
            while ((int)es.size()>=ts){
              auto e=es.back();
              bg[e.F][cc].push_back(e.S);
              bg[e.S][cc].push_back(e.F);
              used[e.S]=1;used[e.F]=1;
              es.pop_back();
            }
            used[x]=0; ++cc;
          }
        }
        h[x]=min(h[x], d[nx]);
      }
    }
    if (p==0){
      if (f>1) cut[x]=1;
      else cut[x]=0;
    }
  }
  Biconnected(vector<int>*g, int n):cut(n+1), h(n+1), d(n+1), used(n+1), bg(n+1){
    cc=1;
    for (int i=1; i<=n; ++i){
      if (d[i]==0){
        d[i]=1;
        dfs(g, i, 0);
      }
    }
  }
};


vector<pair<int, int> >  rt1[101010];
vector<int>              rt2[101010];
vector<pair<int, int> > es;
int main(){
  ios_base::sync_with_stdio(0); cin.tie(0);
  cin >> n >> m;
  for (int i=1; i<=m; ++i){
    int a, b;
    cin >> a >> b;
    es.push_back(MP(a, b));
    rt1[a].push_back(MP(b, i));
    rt1[b].push_back(MP(a, i));
    rt2[a].push_back(b);
    rt2[b].push_back(a);
  }
  int ap=0;
  int br=0;
  Bridges g(rt1, n);
  for (int i=1; i<=m; ++i){
    if (g.c[es[i-1].F]!=g.c[es[i-1].S]){
//       cout << "Bridge " << es[i-1].F << ", " << es[i-1].S << endl;
      ++br;
    }
  }
  Biconnected r(rt2, n);
  for (int i=1; i<=n; ++i){
    if (r.cut[i]){
      ++ap;
//       cout << "cut " << i << endl;
    }
  }
  cout << ap << " " << br << endl;
}

Test details

Test 1

Verdict: ACCEPTED

input
100000 100009
41670 41671
5757 5758
46294 46295
71166 71167
...

correct output
73872 73925

user output
73872 73925