kyopro-lib

This documentation is automatically generated by online-judge-tools/verification-helper

View on GitHub

:warning: Undirected Eulerian path
(Mylib/Graph/EulerianPath/undirected_eulerian_path.cpp)

Operations

Requirements

Notes

Problems

References

Code

#pragma once
#include <map>
#include <optional>
#include <vector>

namespace haar_lib {
  class undirected_eulerian_path {
    int n_, edges_;
    std::vector<std::map<int, int>> g_;
    std::vector<int> deg_;

    void del(int i, int j) {
      if (g_[i][j] == 1)
        g_[i].erase(j);
      else
        --g_[i][j];

      if (g_[j][i] == 1)
        g_[j].erase(i);
      else
        --g_[j][i];
    }

    void dfs(int cur, std::vector<int> &path) {
      if (not g_[cur].empty()) {
        int next = g_[cur].begin()->first;
        del(cur, next);
        dfs(next, path);
      }

      while (not g_[cur].empty()) {
        int next = g_[cur].begin()->first;
        del(cur, next);
        std::vector<int> temp;
        dfs(next, temp);
        path.insert(path.end(), temp.begin(), temp.end());
      }

      path.push_back(cur);
    }

  public:
    undirected_eulerian_path() {}
    undirected_eulerian_path(int n) : n_(n), edges_(0), g_(n), deg_(n) {}

    void add_edge(int i, int j) {
      ++g_[i][j];
      ++g_[j][i];
      ++deg_[i];
      ++deg_[j];
      ++edges_;
    }

    std::optional<std::vector<int>> eulerian_path() {
      std::vector<int> ret;

      int odd = 0, start = 0;
      for (int i = 0; i < n_; ++i) {
        if (deg_[i] % 2 == 1) {
          ++odd;
          start = i;
        }
      }

      if (odd != 0 and odd != 2) return std::nullopt;

      dfs(start, ret);

      if ((int) ret.size() == edges_ + 1) {
        return ret;
      } else {
        return std::nullopt;
      }
    }
  };
}  // namespace haar_lib
#line 2 "Mylib/Graph/EulerianPath/undirected_eulerian_path.cpp"
#include <map>
#include <optional>
#include <vector>

namespace haar_lib {
  class undirected_eulerian_path {
    int n_, edges_;
    std::vector<std::map<int, int>> g_;
    std::vector<int> deg_;

    void del(int i, int j) {
      if (g_[i][j] == 1)
        g_[i].erase(j);
      else
        --g_[i][j];

      if (g_[j][i] == 1)
        g_[j].erase(i);
      else
        --g_[j][i];
    }

    void dfs(int cur, std::vector<int> &path) {
      if (not g_[cur].empty()) {
        int next = g_[cur].begin()->first;
        del(cur, next);
        dfs(next, path);
      }

      while (not g_[cur].empty()) {
        int next = g_[cur].begin()->first;
        del(cur, next);
        std::vector<int> temp;
        dfs(next, temp);
        path.insert(path.end(), temp.begin(), temp.end());
      }

      path.push_back(cur);
    }

  public:
    undirected_eulerian_path() {}
    undirected_eulerian_path(int n) : n_(n), edges_(0), g_(n), deg_(n) {}

    void add_edge(int i, int j) {
      ++g_[i][j];
      ++g_[j][i];
      ++deg_[i];
      ++deg_[j];
      ++edges_;
    }

    std::optional<std::vector<int>> eulerian_path() {
      std::vector<int> ret;

      int odd = 0, start = 0;
      for (int i = 0; i < n_; ++i) {
        if (deg_[i] % 2 == 1) {
          ++odd;
          start = i;
        }
      }

      if (odd != 0 and odd != 2) return std::nullopt;

      dfs(start, ret);

      if ((int) ret.size() == edges_ + 1) {
        return ret;
      } else {
        return std::nullopt;
      }
    }
  };
}  // namespace haar_lib
Back to top page