Advertisement
CyberN00b

a_graph

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