Official

C - Make it Simple Editorial by en_translator


To make the graph simple, i.e. to eliminate self-loops and multi-edges, we need to remove the following two kinds of edges:

  • If there is an edge \((u,v)\) with \(u=v\): it is a self-loop, so it must be always removed.
  • If there are multiple edges \((u,v)\) with \(u \neq v\): they are multi-edges, so all but one must be removed.

Thus, we can count all self-loops into the answer, and for the others, if edge \((u,v)\) occurs \(k\) times, add \((k-1)\) to the answer.

For implementation, it is sufficient to count the occurrence of each edge kind, for which we can use a data structure “dictionary” like std::map in C++. The complexity is \(\mathrm{O}(N \log N)\), which is fast enough. Note that \((u,v)\) and \((v,u)\) must be identified when \(u \neq v\).

Sample code (C++)

#include <iostream>
#include <map>
using namespace std;

int main() {
  cin.tie(0)->sync_with_stdio(0);
  int N, M;
  cin >> N >> M;
  int ans = 0;
  map<pair<int, int>, int> m;
  for (int i = 0; i < M; i++) {
    int u, v;
    cin >> u >> v;
    if (u == v) {
      ans++;
      continue;
    }
    if (u > v) swap(u, v);
    m[{u, v}]++;
  }
  for (auto& [edge, k] : m) ans += k - 1;
  cout << ans << "\n";
}

posted:
last update: