Advertisement
CyberN00b

Untitled

Jan 3rd, 2023
966
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.60 KB | None | 0 0
  1.  
  2. // вторая лабораторная
  3. #include <bits/stdc++.h>
  4.  
  5. using namespace std;
  6.  
  7. template<typename T>
  8. struct Node{
  9.     Node(string name, T mark) : name(std::move(name)), mark(std::move(mark)) {}
  10.  
  11.     vector<pair<long long int, Node*> > vc;
  12.  
  13.     string name;
  14.  
  15.     T mark;
  16. };
  17.  
  18. template<typename T>
  19. struct Graph {
  20.  
  21.     long long int first(Node<T>*& node) {
  22.         if (node->vc.empty())
  23.             return -1;
  24.         return node_to_index[node->vc[0].second];
  25.     }
  26.  
  27.     long long int next(Node<T>*& node, long long int index) {
  28.         long long int i = 0;
  29.         for (; i < node->vc.size(); ++i) {
  30.             if (node_to_index[node->vc[i].second] == index)
  31.                 break;
  32.         }
  33.         if (i < node->vc.size())
  34.             return node_to_index[node->vc[i].second];
  35.         return -1;
  36.     }
  37.  
  38.     Node<T>* vertex(Node<T>*& node, long long int index) {
  39.         if (index < 0)
  40.             return nullptr;
  41.         for (long long int i = 0; i < node->vc.size(); ++i) {
  42.             if (node_to_index[node->vc[i].second] == index)
  43.                 return node->vc[i].second;
  44.         }
  45.         return nullptr;
  46.     }
  47.  
  48.     void add_v(string name, T mark) {
  49.         nodes.push_back(new Node(std::move(name), std::move(mark)));
  50.         node_to_index[nodes.back()] = nodes.size() - 1;
  51.     }
  52.  
  53.     void add_e(Node<T>* first, Node<T>* second, long long int weight, bool is_oriented=true) {
  54.         first->vc.push_back({weight, second});
  55.         if (!is_oriented)
  56.             second->vc.push_back({weight, first});
  57.     }
  58.  
  59.     void del_v(string name) {
  60.         Node<T>* node = get_node(std::move(name));
  61.         for (auto& x : nodes) {
  62.             if (x == node)
  63.                 continue;
  64.             erase_if(x.vc.begin(), x.vc.end(), [node](auto& x){return x.second == node;});
  65.         }
  66.         long long int index = node_to_index[node];
  67.         node_to_index.erase(node);
  68.         nodes.erase(index);
  69.         for (auto& x : node_to_index) {
  70.             if (x.second > index)
  71.                 --x.second;
  72.         }
  73.     }
  74.  
  75.     void del_e(Node<T>* first, Node<T>* second, bool is_oriented=true) {
  76.         erase_if(first->vc.begin(), first->vc.end(), [second](auto& x){return x.second == second;});
  77.         if (!is_oriented)
  78.             erase_if(second->vc.begin(), second->vc.end(), [first](auto& x){return x.second == first;});
  79.     }
  80.  
  81.     void edit_v(Node<T>* node, T mark) {
  82.         node->mark = mark;
  83.     }
  84.  
  85.     void edit_e(Node<T>* first, Node<T>* second, long long int weight, bool is_oriented) {
  86.         replace(first->vc.begin(), first->vc.end(), [second](auto& x){return x.second == second;}, {weight, second});
  87.         if (!is_oriented)
  88.             replace(second->vc.begin(), second->vc.end(), [first](auto& x){return x.second == first;}, {weight, first});
  89.  
  90.     }
  91.  
  92.     void print() { // костыльно зато красиво :3
  93.         if (nodes.empty()) {
  94.             cout << "graph is empty!\n";
  95.             return;
  96.         }
  97.         size_t mx_size = 0;
  98.         for (auto& x : nodes)
  99.             if (x->name.size() > mx_size)
  100.                 mx_size = x->name.size();
  101.         cout << string(mx_size + 1, ' ');
  102.         for (auto& x : nodes)
  103.             cout << x->name << ' ';
  104.         cout << '\n';
  105.         for (auto& x : nodes) {
  106.             cout << string(mx_size - x->name.size(), ' ') << x->name << ' ';
  107.             unordered_map<Node<T>*, long long int> tmp_m(0);
  108.             for (auto& y : x->vc) {
  109.                 if (tmp_m[y.second])
  110.                     tmp_m[y.second] = min(tmp_m[y.second], y.first);
  111.                 else
  112.                     tmp_m[y.second] = y.first;
  113.             }
  114.             for (auto& y : nodes) {
  115.                 string tmp_s = to_string(tmp_m[y]);
  116.                 long long int tmp_i = y->name.size() - tmp_s.size() + 1;
  117.                 cout << string(tmp_i / 2, ' ') << tmp_s << string(tmp_i / 2 + tmp_i % 2, ' ');
  118.             }
  119.             cout << '\n';
  120.         }
  121.     }
  122.  
  123.     Node<T>* get_node(string name) {
  124.         for (auto& x : nodes)
  125.             if (x->name == name)
  126.                 return x;
  127.         return nullptr;
  128.     }
  129.  
  130.     vector<Node<T>*> get_nodes() {
  131.         return nodes;
  132.     }
  133.  
  134. private:
  135.  
  136.     vector<Node<T>*> nodes;
  137.     unordered_map<Node<T>*, size_t> node_to_index;
  138.  
  139. };
  140.  
  141. vector<vector<string> > get_cycles(Graph<int>& g) {
  142.     vector<vector<string> > res;
  143.     for (auto& x : g.get_nodes()) {
  144.         if (!x->mark)
  145.             continue;
  146.         stack<Node<int>*> s;
  147.         g.edit_v(x, 1);
  148.         s.push(x);
  149.         while(!s.empty()) {
  150.             auto top = s.top();
  151.             for (long long int index = g.first(top); index != -1; index = g.next(top, index)) {
  152.                 auto node = g.vertex(top, index);
  153.                 if (node->mark == 2)
  154.                     continue;
  155.                 if (node->mark == 0) {
  156.                     g.edit_v(node, 1);
  157.                     s.push(top);
  158.                     continue;
  159.                 }
  160.                 if (node->mark == 1) {
  161.  
  162.                 }
  163.             }
  164.         }
  165.     }
  166.     return res;
  167. }
  168.  
  169. int main() {
  170.     Graph<pair<int, string>> g;
  171.     int node_count, edge_count;
  172.     while (true) {
  173.         try {
  174.             cout << "Введите кол-во вершин: ";
  175.             cin >> node_count;
  176.             break;
  177.         }
  178.         catch (exception& e) {
  179.             cout << "Неверный ввод! ";
  180.         }
  181.     }
  182.     unordered_set<string> nodes_contained;
  183.     for (int i = 1; i <= node_count; ++i) {
  184.         string t;
  185.         cout << "Введите название " << i << " вершины: ";
  186.         cin >> t;
  187.         g.add_v(t, {0, ""});
  188.         nodes_contained.insert(t);
  189.     }
  190.     while (true) {
  191.         try {
  192.             cout << "Введите кол-во ребер: ";
  193.             cin >> edge_count;
  194.             break;
  195.         }
  196.         catch (exception& e) {
  197.             cout << "Неверный ввод! ";
  198.         }
  199.     }
  200.     for (int i = 0; i < edge_count; ++i) {
  201.         string s1, s2;
  202.         while (true) {
  203.             try {
  204.                 cout << "Введите название двух вершин через пробел, между которыми добавить ребро: ";
  205.                 cin >> s1 >> s2;
  206.                 if (!nodes_contained.contains(s1) || !nodes_contained.contains(s2))
  207.                     throw exception();
  208.                 break;
  209.             } catch(exception& e) {
  210.                 cout << "В графе нет таких вершин! ";
  211.             }
  212.         }
  213.         g.add_e(g.get_node(s1), g.get_node(s2), 1);
  214.     }
  215.     g.print();
  216.     return 0;
  217. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement