Advertisement
zuevv

find euler's cycle in a graph

May 17th, 2019
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.92 KB | None | 0 0
  1. #include<iostream>
  2. #include<fstream>
  3. #include<vector>
  4. #include<stack>
  5. #include<memory>
  6. using namespace std;
  7. struct node {
  8.     int v;
  9.     shared_ptr<node> next;
  10. };
  11. class Graph{
  12.     vector<vector<int>> C;
  13.     shared_ptr<node> loop; //TODO: refactor loop->cycle
  14.     int loopSize;
  15.     int m; //number of edges
  16.     bool isConnected();
  17.     shared_ptr<node> findNextStart();
  18.     shared_ptr<node> findNextLoop(shared_ptr<node> start);
  19. public:
  20.     Graph(int n, vector<pair<int, int>> & E);
  21.     shared_ptr<node> EulerLoop();
  22. };
  23. bool Graph::isConnected() {
  24.     int n = C.size();
  25.     if (n == 0) return true;
  26.     vector<bool> ticked;
  27.     ticked.resize(n);
  28.     stack<int> st;
  29.     st.push(0);
  30.     ticked[0] = true;
  31.     while (st.size()) {
  32.         int v = st.top();
  33.         st.pop();
  34.         for (int i = 0; i < n; i++) {
  35.             if (C[v][i] && !ticked[i]) {
  36.                 ticked[i] = true;
  37.                 st.push(i);
  38.             }
  39.         }
  40.     }
  41.     for(int i=0; i<n; i++){
  42.         if (!ticked[i]) return false;
  43.     }
  44.     for (int i = 0; i < n; i++) {
  45.         int sum = 0;
  46.         for (int j = 0; j < n; j++) sum += C[i][j];
  47.         if (sum % 2) return false;
  48.     }
  49.     return true;
  50. }
  51. shared_ptr<node> Graph::EulerLoop() {
  52.     if(!isConnected()) return NULL;
  53.     while (loopSize < m) {
  54.         auto start = findNextStart();
  55.         if (start == NULL) return NULL;
  56.         auto next = start->next;
  57.         auto end = findNextLoop(start);
  58.         end->next = next;
  59.     }
  60.     auto end = loop;
  61.     while (end->next != NULL) end = end->next;
  62.     if (end->v != loop->v) return NULL;
  63.     return loop;
  64. }
  65. shared_ptr<node> Graph::findNextStart() {
  66.     int n = C.size();
  67.     auto v = loop;
  68.     bool hasEdge = false;
  69.     while (v != NULL) {
  70.         for (int i = 0; i < n; i++) hasEdge |= (bool)(C[v->v][i]);
  71.         if (hasEdge) return v;
  72.         v = v->next;
  73.     }
  74.     return NULL;
  75. }
  76. shared_ptr<node> Graph::findNextLoop(shared_ptr<node> start) {
  77.     int n = C.size();
  78.     auto res = start;
  79.     int v = res->v;
  80.     int u = -1;
  81.     while(true) {
  82.         for (int i = 0; i < n; i++) {
  83.             if (C[v][i]) {
  84.                 C[v][i]--;
  85.                 C[i][v]--;
  86.                 u = i;
  87.                 break;
  88.             }
  89.         }
  90.         if (u == -1) break;
  91.         auto unode = make_shared<node>();
  92.         unode->v = u;
  93.         res->next = unode;
  94.         res = unode;
  95.         loopSize++;
  96.         v = u;
  97.         u = -1;
  98.     }
  99.     return res;
  100. }
  101. Graph::Graph(int n, vector<pair<int, int>> & E) {
  102.     C.resize(n);
  103.     for (int i = 0; i < n; i++) C[i].resize(n);
  104.     for (auto & e : E) {
  105.         C[e.first][e.second]++;
  106.         C[e.second][e.first]++;
  107.     }
  108.     node start;
  109.     start.v = 0;
  110.     loop = make_shared<node>(start);
  111.     m = E.size();
  112.     loopSize = 0;
  113. }
  114.  
  115. void process(istream & in) {
  116.     int n, m, first, second;
  117.     in >> n;
  118.     in >> m;
  119.     vector<pair<int, int>> E;
  120.     for (int i = 0; i < m; i++) {
  121.         in >> first;
  122.         in >> second;
  123.         E.push_back(pair<int, int>(--first, --second));
  124.     }
  125.     Graph g(n, E);
  126.     auto cycle = g.EulerLoop();
  127.     if (cycle == NULL || cycle->next == NULL) cout << "NONE" << endl;
  128.     else {
  129.         while (cycle->next != NULL) {
  130.             cout << ++(cycle->v) << endl;
  131.             cycle = cycle->next;
  132.         }
  133.     }
  134. }
  135.  
  136. int main(void) {
  137.     /*ifstream in("input4.txt");
  138.     process(in);
  139.     in.close();*/
  140.     process(cin);
  141.     return 0;
  142. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement