Advertisement
Guest User

Untitled

a guest
May 26th, 2019
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.60 KB | None | 0 0
  1. main:
  2. #include <iostream>
  3. #include <fstream>
  4. #include <vector>
  5. #include <string>
  6. #include "Graph.h"
  7. using namespace std;
  8.  
  9. int main() {
  10.     try {
  11.         setlocale(LC_ALL, "");
  12.         cout << "Введите имя файла: ";
  13.         string filename;
  14.         cin >> filename;
  15.         ifstream in(filename);
  16.         if (!in.is_open()) {
  17.             throw invalid_argument("file error");
  18.         }
  19.         if (in.peek() == ifstream::traits_type::eof()) {
  20.             throw invalid_argument("empty file");
  21.         }
  22.         int vertexCount;
  23.         in >> vertexCount;
  24.         if (!in || vertexCount < 1) {
  25.             throw invalid_argument("количество вершин - натуральное число");
  26.         }
  27.         Graph a(vertexCount);
  28.         in >> a;
  29.         cout << "Топологически отсортированные вершины: \n";
  30.         vector<int> topSort = topologicalSort(a);
  31.         for (auto & v : topSort) {
  32.             cout << v << ' ';
  33.         }
  34.         cout << "\nМинимальное остовное дерево: \n";
  35.         cout << minOstov(a);
  36.     }
  37.     catch (invalid_argument &error) {
  38.         cerr << error.what() << '\n';
  39.         system("pause");
  40.         return -1;
  41.     }
  42.     system("pause");
  43.     return 0;
  44. }
  45.  
  46.  
  47. Graph.h
  48. #pragma once
  49. #include <vector>
  50. using namespace std;
  51. class Graph
  52. {
  53. private:
  54.     vector<vector<int> > list_;
  55.     vector<vector<int> > table_;
  56.     // dfs
  57.     vector<bool> used_; // вектор, показывающий, была ли посещена вершина
  58.     vector<int> p_; // вектор, показывающий номер предка i-й вершины
  59.     vector<int> d_; // вектор, показывающий время входа в i-ю вершину
  60.     vector<int> f_; // вектор, показывающий время выхода в i-ю вершину
  61.     bool oriented_; // флаг, показывающий, ялвяется ли граф ориентированным
  62.     int time_;
  63.     int size_;
  64. public:
  65.     Graph();
  66.     Graph(const int &vertexCount);
  67.     void addEdge(const int &from, const int &to, const int &wt);
  68.     friend void dfs(Graph &a);
  69.     friend void dfsVisit(Graph &a, const int & u);
  70.     friend vector<int> topologicalSort(Graph &a);
  71.     friend vector<vector<int> > scc(const Graph &a);
  72.     friend Graph minOstov(const Graph &a);
  73.     friend istream& operator>>(istream& in, Graph &a);
  74.     friend ostream& operator<<(ostream& out, Graph a);
  75.     ~Graph();
  76. };
  77.  
  78. Graph.cpp
  79. #include "Graph.h"
  80. #include <iostream>
  81. #include <algorithm>
  82. #include <vector>
  83. #include <functional>
  84. #include <cassert>
  85. using namespace std;
  86.  
  87.  
  88. Graph::Graph() {
  89.     size_ = 0;
  90.     time_ = 0;
  91.     oriented_ = false;
  92. }
  93.  
  94. Graph::Graph(const int &vertexCount) {
  95.     size_ = vertexCount;
  96.     used_.resize(vertexCount, false);
  97.     p_.resize(vertexCount, -1);
  98.     d_.resize(vertexCount);
  99.     f_.resize(vertexCount);
  100.     time_ = 0;
  101.     oriented_ = false;
  102.     list_.resize(vertexCount);
  103.     table_.resize(vertexCount, vector<int>(vertexCount));
  104. }
  105.  
  106. void Graph::addEdge(const int &from, const int &to, const int &wt) {
  107.     table_[from][to] = wt;
  108.     if (wt != 0) {
  109.         list_[from].emplace_back(to);
  110.     }
  111. }
  112.  
  113. Graph::~Graph()
  114. {
  115. }
  116.  
  117. void dfs(Graph &a) {
  118.     for (int u = 0; u < a.size_; ++u) {
  119.         if (!a.used_[u]) {
  120.             dfsVisit(a, u);
  121.         }
  122.     }
  123. }
  124.  
  125. void dfsVisit(Graph &a, const int &u) {
  126.     a.time_++;
  127.     a.d_[u] = a.time_;
  128.     a.used_[u] = true;
  129.     for (auto v : a.list_[u]) {
  130.         if (!a.used_[v]) {
  131.             a.p_[v] = u;
  132.             dfsVisit(a, v);
  133.         }
  134.     }
  135.     a.time_++;
  136.     a.f_[u] = a.time_;
  137. }
  138.  
  139. vector<int> topologicalSort(Graph &a) {
  140.     dfs(a);
  141.     vector<pair<int, int>> unsorted;
  142.     for (int i = 0; i < a.size_; ++i){
  143.         unsorted.push_back({ a.f_[i], i });
  144.     }
  145.     sort(unsorted.begin(), unsorted.end(), greater<pair<int, int>>());
  146.     vector<int> sorted;
  147.     for (int i = 0; i < a.size_; ++i) {
  148.         sorted.push_back(unsorted[i].second);
  149.     }
  150.     return sorted;
  151. }
  152.  
  153. Graph minOstov(const Graph &a) {
  154.     if (a.oriented_) {
  155.         throw invalid_argument("Граф должен быть неориентированным");
  156.     }
  157.     Graph tree(a.size_);
  158.     vector<pair<int, pair<int, int>>> edges;
  159.     for (int i = 0; i < a.size_; ++i) {
  160.         for (int j = i; j < a.size_; ++j) {
  161.             if (a.table_[i][j]) {
  162.                 edges.push_back({ a.table_[i][j], { i, j } });
  163.             }
  164.         }
  165.     }
  166.     sort(edges.begin(), edges.end());
  167.     vector<int> parent(a.size_, -1);
  168.     function<int(int)> getRoot = [&](int v) {
  169.         if (parent[v] < 0) {
  170.             return v;
  171.         }
  172.         else {
  173.             return parent[v] = getRoot(parent[v]);
  174.         }
  175.     };
  176.     function<bool(int, int)> unite = [&](int u, int v) {
  177.         u = getRoot(u);
  178.         v = getRoot(v);
  179.         if (u == v) {
  180.             return false;
  181.         }
  182.         assert(parent[u] < 0);
  183.         assert(parent[v] < 0);
  184.         if (parent[u] < parent[v]) {
  185.             parent[u] += parent[v];
  186.             parent[v] = u;
  187.         }
  188.         else {
  189.             parent[v] += parent[u];
  190.             parent[u] = v;
  191.         }
  192.         return true;
  193.     };
  194.     for (auto const &edge : edges) {
  195.         int wt = edge.first;
  196.         int from = edge.second.first;
  197.         int to = edge.second.second;
  198.         if (unite(from, to)) {
  199.             tree.addEdge(from, to, wt);
  200.             tree.addEdge(to, from, wt);
  201.         }
  202.     }
  203.     return tree;
  204. }
  205.  
  206. istream& operator>>(istream& in, Graph &a) {
  207.     for (int i = 0; i < a.size_; ++i) {
  208.         for (int j = 0; j < a.size_; ++j) {
  209.             int wt;
  210.             in >> wt;
  211.             if (!in || a.table_[i][j] < 0) {
  212.                 throw "нада 0+";
  213.             }
  214.             a.addEdge(i, j, wt);
  215.         }
  216.     }
  217.     a.oriented_ = false;
  218.     for (int i = 0; i < a.size_ && a.oriented_ != true; ++i) {
  219.         for (int j = 0; j < a.size_ && a.oriented_ != true; ++j) {
  220.             if (a.table_[i][j] != a.table_[j][i]) {
  221.                 a.oriented_ = true;
  222.             }
  223.         }
  224.     }
  225.     return in;
  226. }
  227.  
  228. ostream& operator<<(ostream& out, Graph a) {
  229.     for (int i = 0; i < a.size_; ++i) {
  230.         for (int j = (a.oriented_)? 0 : i; j < a.size_; ++j) {
  231.             if (a.table_[i][j]) {
  232.                 cout << "Ребро: " << i << " -> " << j << ". Вес: " << a.table_[i][j] << '\n';
  233.             }
  234.         }
  235.     }
  236.     return out;
  237. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement