Advertisement
CyberN00b

graph

Dec 19th, 2022 (edited)
697
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.74 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. namespace second_lab {
  6.  
  7.     template<typename T>
  8.     struct Node {
  9.  
  10.         string name;
  11.         T mark;
  12.  
  13.         Node(string name): name(name) {}
  14.         Node(string name, T mark): name(name), mark(mark) {}
  15.  
  16.     };
  17.  
  18.     template<typename T>
  19.     struct graph {
  20.  
  21.         graph(long long int node_count=0, T default_mark=nullptr) {
  22.             for (long long int i = 1; i <= node_count; ++i) {
  23.                 node_index[to_string(i)] = i - 1;
  24.                 nodes.push_back(Node<T>(to_string(i), default_mark));
  25.             }
  26.             graph_matrix.resize(node_count);
  27.         }
  28.  
  29.         graph(vector<string> &names, T default_mark=nullptr) {
  30.             for (long long int i = 0; i < names.size(); ++i) {
  31.                 node_index[names[i]] = i;
  32.                 nodes.push_back(Node<T>(names[i], default_mark));
  33.             }
  34.             graph_matrix.resize(names.size());
  35.         }
  36.  
  37.         graph(vector<pair<string, T> > &nodes) {
  38.             for (long long int i = 0; i < nodes.size(); ++i) {
  39.                 node_index[nodes[i].first] = i;
  40.                 nodes.push_back(Node<T>(nodes[i].first, nodes[i].second));
  41.             }
  42.             graph_matrix.resize(nodes.size());
  43.         }
  44.  
  45.         graph(vector<vector<long long int>> matrix, T default_mark=nullptr) {
  46.             graph_matrix = matrix;
  47.             for (long long int i = 1; i <= matrix.size(); ++i) {
  48.                 node_index[to_string(i)] = i - 1;
  49.                 nodes.push_back(Node<T>(to_string(i), default_mark));
  50.             }
  51.         }
  52.  
  53.         vector<vector<long long int> >& get_matrix() {
  54.             return graph_matrix;
  55.         }
  56.  
  57.         vector<Node<T> >& get_nodes() {
  58.             return nodes;
  59.         }
  60.  
  61.         Node<T>* get_node(string name) {
  62.             if (!node_index.contains(name))
  63.                 return nullptr;
  64.             return &nodes[node_index[name]];
  65.         }
  66.  
  67.         Node<T>* first(string name) {
  68.             return next(std::move(name), -1);
  69.         }
  70.  
  71.         Node<T>* vertex(string name, long long int in) {
  72.             return next(std::move(name), in - 1);
  73.         }
  74.  
  75.         Node<T>* next(string name, long long int in) {
  76.             if (!node_index.contains(name))
  77.                 return nullptr;
  78.             long long int index = node_index[name], tmp_index = -1;
  79.             for (long long int i = 0; i < graph_matrix[index].size(); ++i) {
  80.                 if (graph_matrix[index][i] > 0) {
  81.                     if (in-- < 0) {
  82.                         tmp_index = i;
  83.                         break;
  84.                     }
  85.                 }
  86.             }
  87.             if (tmp_index == -1)
  88.                 return nullptr;
  89.             for (long long int i = 0; i < graph_matrix.size(); ++i) {
  90.                 if (i == index)
  91.                     continue;
  92.                 if (graph_matrix[i][tmp_index])
  93.                     return &nodes[i];
  94.             }
  95.             return nullptr;
  96.         }
  97.  
  98.         void add_v(string name, T mark=nullptr) {
  99.             node_index[name] = nodes.size();
  100.             nodes.push_back(Node<T>(name, mark));
  101.             graph_matrix.push_back(*(new vector<long long int>((!graph_matrix.empty())? graph_matrix[0].size() : 0, 0)));
  102.         };
  103.  
  104.         void add_e(string first, string second, long long int weight=1, bool is_oriented=false) {
  105.             for (auto& x : graph_matrix) {
  106.                 x.push_back(0);
  107.             }
  108.             *(graph_matrix[node_index[first]].end() - 1) = weight;
  109.             *(graph_matrix[node_index[second]].end() - 1) = is_oriented? -weight : weight;
  110.         }
  111.  
  112.         void del_v(string name) {
  113.             long long int index = node_index[name];
  114.             for (long long int i = 0; i < graph_matrix[index].size(); ++i)
  115.                 if (graph_matrix[index][i]) {
  116.                     for (auto &x: graph_matrix)
  117.                         x.erase(x.begin() + i);
  118.                 }
  119.             graph_matrix.erase(graph_matrix.begin() + index);
  120.             nodes.erase(nodes.begin() + index);
  121.             node_index.erase(name);
  122.         }
  123.  
  124.         void del_e(string first, string second) {
  125.             long long int f = node_index[first], s = node_index[second], edge_index = -1;
  126.             for (int i = 0; i < graph_matrix[f].size(); ++i) {
  127.                 if (graph_matrix[f][i] && graph_matrix[s][i]) {
  128.                     edge_index = i;
  129.                     break;
  130.                 }
  131.             }
  132.             if (edge_index == -1)
  133.                 return;
  134.             for (auto& x : graph_matrix)
  135.                 x.erase(x.begin() + edge_index);
  136.         }
  137.  
  138.         void edit_v(string node_name, T new_mark) {
  139.             nodes[node_index[node_name]].mark = new_mark;
  140.         }
  141.  
  142.         void edit_e(string first, string second, long long int weight=1, bool is_oriented=false) {
  143.             long long int f = node_index[first], s = node_index[second], edge_index = -1;
  144.             for (int i = 0; i < graph_matrix[f].size(); ++i) {
  145.                 if (graph_matrix[f][i] && graph_matrix[s][i]) {
  146.                     edge_index = i;
  147.                     break;
  148.                 }
  149.             }
  150.             if (edge_index == -1)
  151.                 return;
  152.             graph_matrix[f][edge_index] = weight;
  153.             graph_matrix[s][edge_index] = is_oriented? -weight : weight;
  154.         }
  155.  
  156.     private:
  157.  
  158.         unordered_map<string, long long int> node_index;
  159.         vector<Node<T>> nodes;
  160.         vector<vector<long long int>> graph_matrix;
  161.     };
  162. }
  163. void bfs(second_lab::Node<pair<int, string > >* node, second_lab::graph<pair<int, string > >& g) {
  164.     queue<second_lab::Node<pair<int, string > >*> q;
  165.     q.push(node);
  166.     node->mark.first = 0;
  167.     while (!q.empty()) {
  168.         node = q.front();
  169.         q.pop();
  170.         int index = 0;
  171.         second_lab::Node<pair<int, string > > *v = g.vertex(node->name, 0);
  172.         while (v != nullptr) {
  173.             if (v->mark.first == INT16_MIN) {
  174.                 v->mark.first = node->mark.first + 1;
  175.                 v->mark.second = node->name;
  176.                 q.push(v);
  177.             }
  178.             v = g.vertex(node->name, ++index);
  179.         }
  180.     }
  181. }
  182.  
  183. pair<int, vector<pair<pair<string, string>, vector<string> > > > get_diameter(second_lab::graph<pair<int, string> >& g) { // TODO
  184.     int mx = -1;
  185.     vector<pair<pair<string, string>, vector<string> > > max_range = {};
  186.     set<pair<string, string> > points;
  187.     for (auto& x : g.get_nodes()) {
  188.         for (auto& y : g.get_nodes()) {
  189.             y.mark = {INT16_MIN, ""};
  190.         }
  191.         bfs(&x, g);
  192.         for (auto& y : g.get_nodes()) {
  193.             if (y.mark.first > mx) {
  194.                 mx = y.mark.first;
  195.                 max_range.clear();
  196.                 points.clear();
  197.             }
  198.             if (y.mark.first == mx) {
  199.                 second_lab::Node<pair<int, string > >* tmp = &y;
  200.                 vector<string> vc;
  201.                 do {
  202.                     vc.push_back(tmp->name);
  203.                     tmp = g.get_node(tmp->mark.second);
  204.                 } while (tmp != nullptr);
  205.                 if (!points.count({vc[0], *(vc.end() - 1)}) && !points.count({*(vc.end() - 1), vc[0]})) {
  206.                     points.insert({vc[0], *(vc.end() - 1)});
  207.                     max_range.push_back({{vc[0], *(vc.end() - 1)}, std::move(vc)});
  208.                 }
  209.             }
  210.         }
  211.     }
  212.     return {mx, max_range};
  213. }
  214.  
  215. int main() {
  216.     int a;
  217.     pair<int, vector<pair<pair<string, string>, vector<string> > > > res;
  218.     //cin >> a;
  219.     //second_lab::graph<int> g(a, INT16_MIN);
  220.      /*second_lab::graph<pair<int, string > > g( // --- first
  221.             {{1, 0, 1, 0, 0, 0, 0},
  222.              {1, 1, 0, 0, 0, 0, 0},
  223.              {0, 1, 1, 1, 1, 0, 1},
  224.              {0, 0, 0, 1, 0, 1, 0},
  225.              {0, 0, 0, 0, 1, 1, 0},
  226.              {0, 0, 0, 0, 0, 0, 1}}, {INT16_MIN, ""});*/
  227.     second_lab::graph<pair<int, string > > g(
  228.       {
  229.             {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
  230.             {1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
  231.             {0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0},
  232.             {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1},
  233.             {0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0},
  234.             {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0},
  235.             {0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0},
  236.             {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
  237.             }, {INT16_MIN, ""});
  238.     for (; ; ) {
  239.         int d;
  240.         string t1, t2;
  241.         cin >> d;
  242.         switch (d) {
  243.             case 0:
  244.                 return 0;
  245.             case 1:
  246.                 cin >> t1;
  247.                 g.add_v(t1, {INT16_MIN, {}});
  248.                 break;
  249.             case 2:
  250.                 cin >> t1 >> t2;
  251.                 g.add_e(t1, t2);
  252.                 break;
  253.             case 3:
  254.                 cin >> t1;
  255.                 g.del_v(t1);
  256.                 break;
  257.             case 4:
  258.                 cin >> t1 >> t2;
  259.                 g.del_e(t1, t2);
  260.                 break;
  261.             case 5:
  262.                 res = get_diameter(g);
  263.                 cout << "Diameter is: " << res.first << endl;
  264.                 for (int i = 0; i < res.second.size(); ++i) {
  265.                     cout << "From " << res.second[i].first.first << " to " << res.second[i].first.second << ": ";
  266.                     for (auto& x : res.second[i].second)
  267.                         cout << x << ' ';
  268.                     cout << endl;
  269.                 }
  270.                 break;
  271.             case 6:
  272.                 for (auto& x : g.get_matrix()) {
  273.                     for (auto& y : x)
  274.                         cout << y << ' ';
  275.                     cout << endl;
  276.                 }
  277.                 break;
  278.             case 7:
  279.                 int t;
  280.                 cin >> t1 >> t2 >> t;
  281.                 g.edit_e(t1, t2, t);
  282.         }
  283.     }
  284. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement