Advertisement
999ms

Untitled

Jul 11th, 2020
1,795
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.17 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. template<typename T>
  4. class Graph {
  5. public:
  6.     explicit Graph(int n)
  7.         : n(n)
  8.         , outgoing_arcs(n)
  9.         , incoming_arcs(n)
  10.         , vertex_markers(n, 0)
  11.     {}
  12.  
  13.     class Arc {
  14.     private:
  15.         int from, to;
  16.         T* marker;
  17.     public:
  18.         int GetReceiver() const {
  19.             return to;
  20.         }
  21.        
  22.         int GetPredecessor() const {
  23.             return from;
  24.         }
  25.        
  26.         T* GetMarker() {
  27.             return marker;
  28.         }
  29.        
  30.         Arc(int from, int to)
  31.             : from(from)
  32.             , to(to)
  33.             , marker(new T())
  34.         {}
  35.        
  36.         bool operator == (const Arc& other) const {
  37.             return from == other.from && to == other.to;
  38.         }
  39.     };
  40.  
  41.     class Marker {
  42.     private:
  43.         char id;
  44.         int counter;
  45.         std::unordered_map<unsigned long long, T*> markedValues;
  46.  
  47.     public:
  48.  
  49.         explicit Marker(char id)
  50.             : id(id)
  51.         {}
  52.            
  53.         void Mark(unsigned long long hashValue, T* markerValue) {
  54.             if (((*markerValue >> id) & 1) ^ 1) {
  55.                 counter++;
  56.             }
  57.             *markerValue |= 1ull << id;
  58.             markedValues[hashValue] = markerValue;
  59.         }
  60.        
  61.         char GetId() const {
  62.             return id;
  63.         }
  64.        
  65.         int GetCounter() const {
  66.             return counter;
  67.         }
  68.        
  69.         void Unmark(unsigned long long hashValue, T* markerValue) {
  70.             Mark(hashValue, markerValue);
  71.             *markerValue ^= 1ull << id;
  72.             counter--;
  73.             markedValues.erase(hashValue);
  74.         }
  75.        
  76.         void UnmarkAll() {
  77.             for (auto& [key, value] : markedValues) {
  78.                 Unmark(key, value);
  79.             }
  80.             markedValues = {};
  81.         }
  82.  
  83.     };
  84.    
  85.     char CreateMarker() {
  86.         for (auto& marker : markers) {
  87.             if (marker.GetCounter() == 0) {
  88.                 return marker.GetId();
  89.             }
  90.         }
  91.         char id = markers.size();
  92.         markers.emplace_back(id);
  93.         return id;
  94.     }
  95.    
  96.     std::vector<Marker>& GetMarkers() {
  97.         return markers;
  98.     }
  99.    
  100.     void RemoveMarker(char id) {
  101.         if (markers.size() < id) return;
  102.         markers[id].UnmarkAll();
  103.         if (id + 1 == markers.size()) {
  104.             markers.pop_back();
  105.         }
  106.     }
  107.    
  108.     void MarkArc(Arc& arc, char id) {
  109.         std::cout << "before " << *arc.GetMarker() << std::endl;
  110.         markers[id].Mark(GetArcHash(arc.GetPredecessor(), arc.GetReceiver()), arc.GetMarker());
  111.         std::cout << "after " << *arc.GetMarker() << std::endl;
  112.     }
  113.    
  114.     void MarkVertex(int index, char id) {
  115.         markers[id].Mark(GetVertexHash(index), &vertex_markers[index]);
  116.     }
  117.    
  118.     void UnmarkArc(Arc& arc, char id) {
  119.         markers[id].Unmark(GetArcHash(arc.GetPredecessor(), arc.GetReceiver()), arc.GerMarker());
  120.     }
  121.    
  122.     void UnmarkVertex(int index, char id) {
  123.         markers[id].Mark(GetVertexHash(index), &vertex_markers[index]);
  124.     }
  125.    
  126.     void AddArc(int from, int to) {
  127.         Arc arc(from, to);
  128.         outgoing_arcs[from].push_back(arc);
  129.         incoming_arcs[to].push_back(arc);
  130.     }
  131.    
  132.     void RemoveArc(Arc& arc) {
  133.         int from = arc.GetPredecessor();
  134.         int to = arc.GetReceiver();
  135.         int marker = arc.GetMarker();
  136.         const auto arcHash = GetArcHash(from, to);
  137.         for (char id = 0; id < char(std::size(markers)); id++) {
  138.             if ((marker >> id) & 1) {
  139.                 markers[id].Unmark(arcHash, arc.GetMarker());
  140.             }
  141.         }
  142.         for (size_t i = 0; i < outgoing_arcs[from].size(); i++) {
  143.             if (outgoing_arcs[from][i] == arc) {
  144.                 std::swap(outgoing_arcs[from][i], outgoing_arcs[from].back());
  145.                 outgoing_arcs[from].pop_back();
  146.                 break;
  147.             }
  148.         }
  149.         for (size_t i = 0; i < incoming_arcs[to].size(); i++) {
  150.             if (incoming_arcs[to][i] == arc) {
  151.                 std::swap(incoming_arcs[to][i], incoming_arcs[to].back());
  152.                 incoming_arcs[to].pop_back();
  153.                 break;
  154.             }
  155.         }
  156.     }
  157.    
  158.     std::vector<Arc>& GetOutgoingArcs(int from) {
  159.         return outgoing_arcs[from];
  160.     }
  161.    
  162.     std::vector<Arc>& GetIncomingArcs(int to) {
  163.         return incoming_arcs[to];
  164.     }
  165.    
  166.    
  167. private:
  168.     unsigned long long GetVertexHash(int index_of_vertex) {
  169.         return index_of_vertex << 1;
  170.     }
  171.    
  172.     unsigned long long GetArcHash(int from, int to) {
  173.         return ((unsigned long long)(n) * n * from + n * to) << 1 | 1;
  174.     }
  175.  
  176.     int n;
  177.     std::vector<std::vector<Arc>> outgoing_arcs;
  178.     std::vector<std::vector<Arc>> incoming_arcs;   
  179.     std::vector<T> vertex_markers;
  180.     std::vector<Marker> markers;
  181. };
  182.  
  183. int main() {
  184.     const int n = 5;
  185.     Graph<int> graph(n);
  186.     std::vector<std::pair<int,int>> arcs = {
  187.         {0, 1},
  188.         {1, 2},
  189.         {2, 3},
  190.         {3, 4},
  191.         {4, 0}
  192.     };
  193.    
  194.     for (auto& [from, to] : arcs) {
  195.         graph.AddArc(from, to);
  196.     }
  197.    
  198.     auto marker = graph.CreateMarker();
  199.     for (int i = 0; i < n; i++) {
  200.         auto outgoing = graph.GetOutgoingArcs(i);
  201.         for (auto& arc : outgoing) {
  202.             if (rand() & 1) graph.MarkArc(arc, marker);
  203.         }
  204.     }
  205.    
  206.     auto marker2 = graph.CreateMarker();
  207.     for (int i = 0; i < n; i++) {
  208.         auto outgoing = graph.GetOutgoingArcs(i);
  209.         for (auto& arc : outgoing) {
  210.             if (rand() & 2) graph.MarkArc(arc, marker2);
  211.         }
  212.     }
  213.    
  214.     for (int i = 0; i < n; i++) {
  215.         auto outgoing = graph.GetOutgoingArcs(i);
  216.         for (auto& arc : outgoing) {
  217.             std::cout << *arc.GetMarker() << ' ';
  218.         }
  219.     }
  220.     std::cout << std::endl;
  221.    
  222.     graph.GetMarkers()[marker].UnmarkAll();
  223.     for (int i = 0; i < n; i++) {
  224.         auto outgoing = graph.GetOutgoingArcs(i);
  225.         for (auto& arc : outgoing) {
  226.             std::cout << *arc.GetMarker() << ' ';
  227.         }
  228.     }
  229.     std::cout << std::endl;
  230.    
  231.     graph.GetMarkers()[marker2].UnmarkAll();
  232.     for (int i = 0; i < n; i++) {
  233.         auto outgoing = graph.GetOutgoingArcs(i);
  234.         for (auto& arc : outgoing) {
  235.             std::cout << *arc.GetMarker() << ' ';
  236.         }
  237.     }
  238.     std::cout << std::endl;
  239. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement